根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/
9 20
/
15 7
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
DFS(pos_in_preorder,pos_in_inorder,sizeof_tree)
三个参数分别是树在先序、中序的开始位置和树的大小。
当然,使用常见的
(left,right)
来表示树的位置亦可,看哪种让自己的思路更加清晰。例如,二分的时候使用while(len > 0)
让我少了很对对死循环的担心[捂脸]
一些优化:使用 map<int,int>
记录值在中序的位置;用 unordered_map<int,int>
比 map<int,int>
测试结果更优。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
TreeNode* DFS(vector<int>&preo,vector<int>&ino,unordered_map<int, int>&pos_in_inorder,int pp, int ip, const int n){
if(n == 0)
return NULL;
TreeNode * root = new TreeNode(preo[pp]);
int i = pos_in_inorder[preo[pp]] - ip;
if(ino[ip + i] == preo[pp]) {
root->left = DFS(preo,ino,pos_in_inorder,pp + 1, ip, i);
root->right = DFS(preo,ino,pos_in_inorder,pp + i + 1, ip + i + 1, n - i - 1);
return root;
}
return NULL;
}
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() == 0 )
return NULL;
unordered_map<int, int>pos_in_inorder;
for(int i = 0; i < inorder.size(); ++i)
pos_in_inorder[inorder[i]] = i;
return DFS(preorder,inorder,pos_in_inorder,0, 0, preorder.size());
}
};