由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - Construct Binary Tree from Preorder and Inorder Traversal算法复杂度?
相关主题
[leetcode] Binary Tree from Inorder & Postorder Traversal这个inorder traversal 有错嘛,为什么leetcode 总报memory limit exceed?
Construct Binary Tree from Inorder and Postorder Traversal大牛帮我看看这哪错了? iterative inorder traversal
讨论一道leetcode上面的题inorder traversal的空间复杂度是O(N) 还是O(logN)?
construct tree with preorder and inorder[合集] 微软面试的一道题
这道题如何得到最优解F家phone interview的一道题
construct bst from post and inorder 总是Memory Limit Exceeded请教大家一个问题:Maximum Height (Depth) of a Binary Tree Using PreOrder Traversal
有没有人同觉得Recover Binary Search Tree的solution using O(n) space并不是那么straight forward么?Construct Binary Tree from Preorder and Inorder Traversal的setup 是不是有点问题?
再来bitch一下麻烦大家帮看看这段代码的问题
相关话题的讨论汇总
话题: treenode话题: preorder话题: inorder话题: int话题: pre
进入JobHunting版参与讨论
1 (共1页)
a***e
发帖数: 413
1
下面这两个1.2.写法都是O(N^2)吧?为啥2说是O(N)呢?另外,看到lc上一个
discussion的iterative的解法3.https://oj.leetcode.com/discuss/2297/the-
iterative-solution-is-easier-than-you-think
时间复杂度是O(N)吧?
我看了helper的function signature能写出1,对2中用到的好多STL要搜索才能写出来
,不熟。
Binary tree和recursion现在是我最弱处,多谢!
1.
class Solution {
public:
TreeNode *buildTree(vector &preorder, vector &inorder) {
if (preorder.size()==0) return NULL;
else if (preorder.size()==1)
{
TreeNode *t = new TreeNode(preorder[0]);
return t;
}
else
return helper(preorder, inorder, 0, inorder.size()-1,0);
}

TreeNode *helper(vector &preorder, vector &inorder, int start,
int end, int rIdx)
{
if (start>end)
return NULL;
TreeNode *r = new TreeNode(preorder[rIdx]);
int mid=0;
for (int i=start; i<=end; i++)
{
if (inorder[i]==preorder[rIdx])
{
mid = i;
break;
}
}
r->right = helper(preorder, inorder,mid+1,end,rIdx+mid-start+1);
r->left = helper(preorder,inorder,start,mid-1,rIdx+1);
return r;
}
};
2.// LeetCode, Construct Binary Tree from Preorder and Inorder Traversal
// 递归,时间复杂度O(n),空间复杂度O(logn)
class Solution {
public:
TreeNode* buildTree(vector& preorder, vector& inorder) {
return buildTree(begin(preorder), end(preorder),
begin(inorder), end(inorder));
}
template
TreeNode* buildTree(InputIterator pre_first, InputIterator pre_last,
InputIterator in_first, InputIterator in_last) {
if (pre_first == pre_last) return nullptr;
if (in_first == in_last) return nullptr;
auto root = new TreeNode(*pre_first);
auto inRootPos = find(in_first, in_last, *pre_first);
auto leftSize = distance(in_first, inRootPos);
root->left = buildTree(next(pre_first), next(pre_first,
leftSize + 1), in_first, next(in_first, leftSize));
root->right = buildTree(next(pre_first, leftSize + 1), pre_last,
next(inRootPos), in_last);
return root;
}
};
f*******w
发帖数: 1243
2
应该都是n^2吧。这两个方法好像没有任何区别啊。
除非find()还有什么特别的技巧?不过在没排序的vector里面查找肯定是O(n)了。
如果数组没重复的话,可以先把inorder存在hash里,key是数组里面的值,value是
index。这样能做到O(n) in time.
a***e
发帖数: 413
3
多谢大牛,我觉得它们都是O(N^2),但看2说自己是O(N)又不确定了。
下面这种解法应该怎么分析复杂度呢?我觉得是O(N)但还是不确定。
class Solution {
public:
TreeNode *buildTree(vector &pre, vector &in) {
int i=0,j=0;
TreeNode *root=new TreeNode(0x80000000);
TreeNode *pp=NULL,*ptr=root;
stack sn;sn.push(root);
while (j if (sn.top()->val==in[j]) {
pp=sn.top();
sn.pop();
j++;
} else if (pp) {
ptr=new TreeNode(pre[i]);
pp->right=ptr;pp=NULL;
sn.push(ptr);
i++;
} else {
ptr=new TreeNode(pre[i]);
sn.top()->left=ptr;
sn.push(ptr);
i++;
}
}
ptr=root->left;delete root;
return ptr;
}
};
b******g
发帖数: 3616
4
这个应该是O(N)了,除了第一个元素外,其他每个元素进出栈一次,而且i,j各扫描pre
,in一次。
这个算法很牛啊,虽然follow了个简单的例子觉得算法应该是对的,但还没有完全理解
是什么原理。请高手解释!

【在 a***e 的大作中提到】
: 多谢大牛,我觉得它们都是O(N^2),但看2说自己是O(N)又不确定了。
: 下面这种解法应该怎么分析复杂度呢?我觉得是O(N)但还是不确定。
: class Solution {
: public:
: TreeNode *buildTree(vector &pre, vector &in) {
: int i=0,j=0;
: TreeNode *root=new TreeNode(0x80000000);
: TreeNode *pp=NULL,*ptr=root;
: stack sn;sn.push(root);
: while (j
a***e
发帖数: 413
5
这个是在leetcode的讨论中一个叫dtx0的同学贴的。
gpraveenkumar的idea和他/她的几乎一样
The idea is as follows: 程序中没用flag,而是用pp这个指针
1) Keep pushing the nodes from the preorder into a stack (and keep making
the tree by adding nodes to the left of the previous node) until the top of
the stack matches the inorder.
2) At this point, pop the top of the stack until the top does not equal
inorder (keep a flag to note that you have made a pop).
3) Repeat 1 and 2 until preorder is empty. The key point is that whenever
the flag is set, insert a node to the right and reset the flag.
我仔细看了,觉得算法很巧妙。
我的理解是根据preorder inorder的基本原理,
1)能够保证左子树都入栈
2)3)中pop出来的node的左子树都在栈下面压着,所以在preorder里面的下一个肯定
是right child。
不知道怎么正式的证明,期待大牛们的讨论。
1 (共1页)
进入JobHunting版参与讨论
相关主题
麻烦大家帮看看这段代码的问题这道题如何得到最优解
这个rebuild binary tree的问题construct bst from post and inorder 总是Memory Limit Exceeded
请教个G题目有没有人同觉得Recover Binary Search Tree的solution using O(n) space并不是那么straight forward么?
攒人品,amazon一面经历再来bitch一下
[leetcode] Binary Tree from Inorder & Postorder Traversal这个inorder traversal 有错嘛,为什么leetcode 总报memory limit exceed?
Construct Binary Tree from Inorder and Postorder Traversal大牛帮我看看这哪错了? iterative inorder traversal
讨论一道leetcode上面的题inorder traversal的空间复杂度是O(N) 还是O(logN)?
construct tree with preorder and inorder[合集] 微软面试的一道题
相关话题的讨论汇总
话题: treenode话题: preorder话题: inorder话题: int话题: pre