Careercup - Google面试题 - 5162732873580544
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的更多相关文章
- Careercup - Google面试题 - 5732809947742208
2014-05-03 22:10 题目链接 原题: Given a dictionary, and a list of letters ( or consider as a string), find ...
- Careercup - Google面试题 - 5085331422445568
2014-05-08 23:45 题目链接 原题: How would you use Dijkstra's algorithm to solve travel salesman problem, w ...
- Careercup - Google面试题 - 4847954317803520
2014-05-08 21:33 题目链接 原题: largest number that an int variable can fit given a memory of certain size ...
- Careercup - Google面试题 - 6332750214725632
2014-05-06 10:18 题目链接 原题: Given a ,) (,) (,), (,) should be returned. Some suggest to use Interval T ...
- Careercup - Google面试题 - 5634470967246848
2014-05-06 07:11 题目链接 原题: Find a shortest path ,) to (N,N), assume is destination, use memorization ...
- Careercup - Google面试题 - 5680330589601792
2014-05-08 23:18 题目链接 原题: If you have data coming in rapid succession what is the best way of dealin ...
- Careercup - Google面试题 - 5424071030341632
2014-05-08 22:55 题目链接 原题: Given a list of strings. Produce a list of the longest common suffixes. If ...
- Careercup - Google面试题 - 5377673471721472
2014-05-08 22:42 题目链接 原题: How would you split a search query across multiple machines? 题目:如何把一个搜索que ...
- Careercup - Google面试题 - 6331648220069888
2014-05-08 22:27 题目链接 原题: What's the tracking algorithm of nearest location to some friends that are ...
随机推荐
- VMware下安装的Mac OS X如何修改显示分辨率
VMware下安装的Mac OS X如何修改显示分辨率 我在Win7下利用VMware安装了苹果的Mac OS,安装成功启动后,发现分辨率为1920*1080,而宿机的分辨率是1366*768,我 ...
- HTML自动换行的问题
有时文本文字已经超过所在的区域,但是文字还是不自动换行 可以用强制换行 强制不换行div{ white-space:nowrap;}自动换行div{ word-wrap:break-word; wor ...
- VS2010 自动关闭的问题解决方法
分为如下几个解决方法: 没有安装VS2010的SP1,安装后,问题解决了 自定义设置,出现了不正确的情况,执行 devenv.exe /resetsettings 可以排除故障 使用 devenv.e ...
- ASP.NET中实现页面间的参数传递
ASP.NET中实现页面间的参数传递 编写人:CC阿爸 2013-10-27 l 近来在做泛微OA与公司自行开发的系统集成登录的问题.在研究泛微页面间传递参为参数,综合得了解了一下现行页面间传参 ...
- Oracle删除表主键语句
删除无名主键语句: SELECT * FROM USER_CONS_COLUMNS WHERE TABLE_NAME = '表名'; ALTER TABLE 表名 DROP CONSTRAINT 主键 ...
- tomcat学习笔记1
tomcat是一个开源软件,是由java语言编写的,它工作的话需要运行在jvm虚拟机中,说到jvm不得不说下java这个大名鼎鼎的编程 语言了 java这个编程语言最优秀的特点要数write once ...
- Nginx配置:http重定向,URLRewrite,一个简单框架的配置思路
一个重定向的应用配置: server { listen 8000; server_name localhost; root F:/home/projects/test; index ...
- 获取月份对应的day
function getDaysInMonth(month, year) { , , , , , , , , , , , ]; //主要处理二月份的天数 ) && (year % == ...
- WCF中使用控件的委托,线程中的UI委托
UI界面: <Window x:Class="InheritDemo.Window1" xmlns="http://schemas.microsoft.com/wi ...
- virtualenv 安装
virtualenv 是一个创建隔离的Python环境的工具. virtualenv要解决的根本问题是库的版本和依赖,以及权限问题.假设你有一个程序,需要LibFoo的版本1,而另一个程序需要版本2, ...