输入一棵二叉树前序遍历和中序遍历的结果,请重建该二叉树。
注意:
二叉树中每个节点的值都互不相同;
输入的前序遍历和中序遍历一定合法;
样例
给定: 前序遍历是:[3, 9, 20, 15, 7] 中序遍历是:[9, 3, 15, 20, 7] 返回:[3, 9, 20, null, null, 15, 7, null, null, null, null] 返回的二叉树如下所示: 3 / \ 9 20 / \ 15 7
/**
* 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 {
public:
unordered_map<int,int> pos;
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
//记录下根节点在中序的位置
int n=preorder.size();
for(int i=0;i<n;i++){
pos[inorder[i]]=i; //inorder[i]表示inorder[i]前序根节点的位置
}
return buildChild(preorder,inorder,0,n-1,0,n-1);
}
TreeNode* buildChild(vector<int>& preorder, vector<int>& inorder,int preStart,int preEnd,int inStart,int inEnd){
if(preStart>preEnd) return NULL;
TreeNode* root=new TreeNode(preorder[preStart]);
int k=pos[preorder[preStart]]-inStart;//中序起点到根节点个数
//左孩子前序范围prestart+1~prestart+k 中序范围:inStart~k-1
root->left=buildChild(preorder,inorder,preStart+1,preStart+k,inStart,inStart+k-1);
//右孩子前序范围prestart+k+1~preend,中序范围 k+1,inEnd
root->right=buildChild(preorder,inorder,preStart+k+1,preEnd,inStart+k+1,inEnd);
return root;
}
};思路,二叉树建树要想到的思路就是要自底向上建树,自然需要用到递归思想,即先建左右子树,再连上根节点。
首先利用前序遍历找到根节点,前序的第一个数就是根节点
在中序中找到根节点位置k,k左边就是左子树的中序遍历,右边就是右子树的中序遍历
计算下左子树中序遍历长度L,在前序中根节点后面的L个数就是左子树的前序遍历,剩下的就是右子树的前序
根据左右子树的前序和中序,递归创建左右子树
创建根节点,完成

有话要说...