根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
next
next(x) 相当于 next(1)
next(x,n) 相当于以x为数组0元素位置的x(n)
思路图解
https://github.com/soulmachine/leetcode
class Solution {
public:
template<typename T>
TreeNode* buildTree(T prefirst,T prelast,T infirst,T inlast){
if(prefirst==prelast) return nullptr;
if(infirst==inlast) return nullptr;
auto root=new TreeNode(*prefirst);
auto inRootPos=find(infirst,inlast,*prefirst);
auto leftSize=distance(infirst,inRootPos);
// 第leftSize个元素并不在左子树中,而包含在右子树中
root->left=buildTree(next(prefirst),next(prefirst,leftSize+1),
infirst,inRootPos);
root->right=buildTree(next(prefirst,leftSize+1),prelast,next(inRootPos),inlast);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return buildTree(begin(preorder),end(preorder),begin(inorder),end(inorder));
}
};
class Solution {
public:
template<typename T>
TreeNode* buildTree(T prefirst,T prelast,T infirst,T inlast){
cout<<"prefirst : " << *prefirst <<endl;
cout<<"prelast : " << *prelast <<endl;
cout<<"infirst : "<< *infirst <<endl;
cout<<"inlast : " << *inlast <<endl;
if(prefirst==prelast) return nullptr;
if(infirst==inlast) return nullptr;
auto root=new TreeNode(*prefirst);
auto inRootPos=find(infirst,inlast,*prefirst);
auto leftSize=distance(infirst,inRootPos);
cout<<"leftSize : " << leftSize <<endl;
cout<<"-------------------------------------------------"<<endl;
root->left=buildTree(next(prefirst),next(prefirst,leftSize+1),infirst,next(infirst,leftSize));
root->right=buildTree(next(prefirst,leftSize+1),prelast,next(inRootPos),inlast);
return root;
}
执行用时 | 内存消耗 |
---|---|
12 ms | 25.8 MB |
prefirst : 3
prelast : -1094795586
infirst : 9
inlast : -1094795586
leftSize : 1
-------------------------------------------------
prefirst : 9
prelast : 20
infirst : 9
inlast : 3
leftSize : 0
-------------------------------------------------
prefirst : 20
prelast : 20
infirst : 9
inlast : 9
prefirst : 20
prelast : 20
infirst : 3
inlast : 3
prefirst : 20
prelast : -1094795586
infirst : 15
inlast : -1094795586
leftSize : 1
-------------------------------------------------
prefirst : 15
prelast : 7
infirst : 15
inlast : 20
leftSize : 0
-------------------------------------------------
prefirst : 7
prelast : 7
infirst : 15
inlast : 15
prefirst : 7
prelast : 7
infirst : 20
inlast : 20
prefirst : 7
prelast : -1094795586
infirst : 7
inlast : -1094795586
leftSize : 0
-------------------------------------------------
prefirst : -1094795586
prelast : -1094795586
infirst : 7
inlast : 7
prefirst : -1094795586
prelast : -1094795586
infirst : -1094795586
inlast : -1094795586
[3, 9, 20, null, null, 15, 7, null, null, null, null]
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size()==0) return nullptr;
TreeNode *root=new TreeNode(preorder[0]);
int length=preorder.size();
stack<TreeNode*> s;
s.push(root);
int inorderIndex=0;
for(int i=1;i<length;i++){
int preorderVal=preorder[i];
TreeNode *Node=s.top();
if(Node->val!=inorder[inorderIndex]){
Node->left=new TreeNode(preorderVal);
s.push(Node->left);
}
else{
while(!s.empty()&&s.top()->val==inorder[inorderIndex]){
Node=s.top();
s.pop();
inorderIndex++;
}
Node->right=new TreeNode(preorderVal);
s.push(Node->right);
}
}
return root;
}
};
执行用时 | 内存消耗 |
---|---|
12 ms | 19.1 MB |
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size()==0) return nullptr;
TreeNode *root=new TreeNode(preorder[0]);
int length=preorder.size();
stack<TreeNode*> s;
s.push(root);
int inorderIndex=0;
for(int i=1;i<length;i++){
cout<<"i= "<<i<<endl;
int preorderVal=preorder[i];
cout<<"preorderVal= "<<preorderVal<<endl;
TreeNode *Node=s.top();
cout<<"Node= "<<Node->val<<endl;
cout<<"inorderIndex= "<<inorderIndex<<endl;
cout<<"inorder[inorderIndex]= "<<inorder[inorderIndex]<<endl;
if(Node->val!=inorder[inorderIndex]){
Node->left=new TreeNode(preorderVal);
s.push(Node->left);
}
else{
while(!s.empty()&&s.top()->val==inorder[inorderIndex]){
Node=s.top();
s.pop();
inorderIndex++;
cout<<"@ inorderIndex= "<<inorderIndex<<endl;
}
Node->right=new TreeNode(preorderVal);
s.push(Node->right);
}
}
return root;
}
};
stdin
[3,9,8,5,4,10,20,15,7]
[4,5,8,10,9,3,15,20,7]
3
/ \
9 20
/ / \
8 15 7
/ \
5 10
/
4
i= 1
preorderVal= 9
Node= 3
inorderIndex= 0
inorder[inorderIndex]= 4
i= 2
preorderVal= 8
Node= 9
inorderIndex= 0
inorder[inorderIndex]= 4
i= 3
preorderVal= 5
Node= 8
inorderIndex= 0
inorder[inorderIndex]= 4
i= 4
preorderVal= 4
Node= 5
inorderIndex= 0
inorder[inorderIndex]= 4
i= 5
preorderVal= 10
Node= 4
inorderIndex= 0
inorder[inorderIndex]= 4
@ inorderIndex= 1
@ inorderIndex= 2
@ inorderIndex= 3
i= 6
preorderVal= 20
Node= 10
inorderIndex= 3
inorder[inorderIndex]= 10
@ inorderIndex= 4
@ inorderIndex= 5
@ inorderIndex= 6
i= 7
preorderVal= 15
Node= 20
inorderIndex= 6
inorder[inorderIndex]= 15
i= 8
preorderVal= 7
Node= 15
inorderIndex= 6
inorder[inorderIndex]= 15
@ inorderIndex= 7
@ inorderIndex= 8
[3, 9, 20, 8, null, 15, 7, 5, 10, null, null, null, null, 4, null, null, null, null, null]