2014-05-08 08:26

题目链接

原题:

Given a preorder traversal, create a binary search tree in optimized time

题目:给定一个二叉搜索树的前序遍历,请重建这棵树。要求最优化算法。

解法1:这人每次出题都要求“最优算法”,自己写的代码却实在让人汗颜,让人觉得这家伙就是懒得思考,想从别人那儿问答案。前序遍历的顺序是“根左右”,那么根节点之后所有小于根的部分就是左子树,后面就是右子树了。怎么找这条分界线呢?可以顺着找。那么算法的复杂度就是O(n * log(n))了。复杂度的证明参考归并排序即可。这个算法可行,但不是最优。

代码:

 // http://www.careercup.com/question?id=5162732873580544
#include <iostream>
#include <vector>
using namespace std; struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int _val = ): val(_val), left(nullptr), right(nullptr) {};
}; void constructBSTFromPreorderTraversal(vector<int> &v, int ll, int rr, TreeNode *&root)
{
root = new TreeNode(v[ll]); int i = ll + ;
while (i <= rr && v[i] < v[ll]) {
++i;
}
if (ll + <= i - ) {
constructBSTFromPreorderTraversal(v, ll + , i - , root->left);
}
if (i <= rr) {
constructBSTFromPreorderTraversal(v, i, rr, root->right);
}
} void inorderTraversal(TreeNode *root)
{
if (nullptr == root) {
return;
}
inorderTraversal(root->left);
cout << root->val << ' ';
inorderTraversal(root->right);
} void clearTree(TreeNode *&root)
{
if (nullptr == root) {
return;
}
clearTree(root->left);
clearTree(root->right);
delete root;
root = nullptr;
} int main()
{
vector<int> v;
int n;
int i;
TreeNode *root; while (cin >> n && n > ) {
v.resize(n);
for (i = ; i < n; ++i) {
cin >> v[i];
}
root = nullptr;
constructBSTFromPreorderTraversal(v, , n - , root);
inorderTraversal(root);
cout << endl; clearTree(root);
v.clear();
} return ;
}

解法2:既然遍历是O(n)时间完成的,重建应该也可以做到O(n)。我的思路,是比较三个节点的值:父节点,当前节点,新节点。根据它们之间的大小关系可以判断新的节点应该插入在哪儿。代码中的关键部分很短,所以不需要多余解释了。其中用到了一个节点栈,用于回溯。所以这个算法用递归来写也是同样直观的。

 // http://www.careercup.com/question?id=5162732873580544
#include <iostream>
#include <vector>
using namespace std; struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int _val = ): val(_val), left(nullptr), right(nullptr) {};
}; void inorderTraversal(TreeNode *root)
{
if (nullptr == root) {
return;
}
inorderTraversal(root->left);
cout << root->val << ' ';
inorderTraversal(root->right);
} void clearTree(TreeNode *&root)
{
if (nullptr == root) {
return;
}
clearTree(root->left);
clearTree(root->right);
delete root;
root = nullptr;
} int main()
{
vector<int> v;
int n;
int i;
TreeNode *root;
TreeNode *tmp;
vector<TreeNode *> st; while (cin >> n && n > ) {
v.resize(n);
for (i = ; i < n; ++i) {
cin >> v[i];
} root = new TreeNode(v[]);
st.push_back(root);
for (i = ; i < n; ++i) {
if (v[i] < st[st.size() - ]->val) {
tmp = new TreeNode(v[i]);
st[st.size() - ]->left = tmp;
st.push_back(tmp);
} else if (st.size() == || v[i] < st[st.size() - ]->val) {
tmp = new TreeNode(v[i]);
st[st.size() - ]->right = tmp;
st.push_back(tmp);
} else {
st.pop_back();
--i;
}
} inorderTraversal(root);
cout << endl; v.clear();
st.clear();
clearTree(root);
} return ;
}

Careercup - Google面试题 - 5162732873580544的更多相关文章

  1. Careercup - Google面试题 - 5732809947742208

    2014-05-03 22:10 题目链接 原题: Given a dictionary, and a list of letters ( or consider as a string), find ...

  2. Careercup - Google面试题 - 5085331422445568

    2014-05-08 23:45 题目链接 原题: How would you use Dijkstra's algorithm to solve travel salesman problem, w ...

  3. Careercup - Google面试题 - 4847954317803520

    2014-05-08 21:33 题目链接 原题: largest number that an int variable can fit given a memory of certain size ...

  4. Careercup - Google面试题 - 6332750214725632

    2014-05-06 10:18 题目链接 原题: Given a ,) (,) (,), (,) should be returned. Some suggest to use Interval T ...

  5. Careercup - Google面试题 - 5634470967246848

    2014-05-06 07:11 题目链接 原题: Find a shortest path ,) to (N,N), assume is destination, use memorization ...

  6. Careercup - Google面试题 - 5680330589601792

    2014-05-08 23:18 题目链接 原题: If you have data coming in rapid succession what is the best way of dealin ...

  7. Careercup - Google面试题 - 5424071030341632

    2014-05-08 22:55 题目链接 原题: Given a list of strings. Produce a list of the longest common suffixes. If ...

  8. Careercup - Google面试题 - 5377673471721472

    2014-05-08 22:42 题目链接 原题: How would you split a search query across multiple machines? 题目:如何把一个搜索que ...

  9. Careercup - Google面试题 - 6331648220069888

    2014-05-08 22:27 题目链接 原题: What's the tracking algorithm of nearest location to some friends that are ...

随机推荐

  1. 设计模式-代理模式(Proxy)

    应用场景: 领导都有秘书,一般会代理领导的部分职能角色,处理签字.报销.开会等任务.很多新人可能都只知道秘书的存在,毕竟每天与其打交道,不知道领导的存在.但是领导的的确确是真实存在的. 场景说明: 代 ...

  2. 设计模式-外观模式(Facade)

    简介 外观模式(Facade),将外部与内部子系统的通信通过一个统一的门面对象进行. 由两部分组成: 门面角色:供外部调用,内部可能组装了多个子系统,多个方法. 子系统角色:子系统的方法也可以直接供外 ...

  3. libharu 源码编译 VS2010

    最近项目中接过了一个libharu PDF 开源库的锅,哈哈.于是就自己编译了一套libharu 的MFC下的静态库和动态库. 编译libharu需要用到zlib库和libpng库,libpng库又依 ...

  4. DevExpress之ASPxGridView笔记(1)

    1.设置Row(某列)输出格式,例如,在数字前加美元符.每3位以逗号隔开及设置小数点后两位: <dx:GridViewDataTextColumn FieldName="SHOUHUI ...

  5. 【自己动手】sublime text插件开发

    今天是五四青年节,在此先祝大家节日快乐!!! --------------------------------------------华丽的分界线--------------------------- ...

  6. C++ string 转 char*

    string 转到 char* char name[20]; string sname=GatherName[n]; strcpy(name,sname.c_str());

  7. 通过URLHttpConnection方式连接网络步骤,获取位图为例

    要注意的是:访问网络不能直接放在主线程,要放在另外一个线程里面,如果放在主线程会报android.os.NetworkOnMainThreadException错误1 public Bitmap ge ...

  8. equals方法,hashcode()方法

    Object类的equals 方法 用来检测两个对象是否相等,即两个对象的内容是否相等,区分大小写.   (一)说到equals方法,不得不提一下==号. ==用于比较引用和比较原生数据类型时具有不同 ...

  9. oracle分区表(整理)

    Oracle 表分区 早在8.0.5版本中,Oracle就将范围分区技术引入,现在分区功能已经越来越强大,包括支持扩展分区功能.Interval分区.外键分区.模拟列分区.以及分区建议器等.那么,分区 ...

  10. hdu 5224 Tom and paper

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5224 Tom and paper Description There is a piece of pa ...