根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3 / \ 9 20 / \ 15 7
思路:前序遍历先访问根节点,因此前序遍历序列的第一个字母肯定就是根节点,即3是根节点;然后,由于中序遍历先访问左子树,再访问根节点,最后访问右子树,所以我们找到中序遍历中3的位置,然后3左边的字母就是左子树了,也就是9是根节点的左子树;同样的,得到15,20,7为根节点的右子树。
将前序遍历序列分成9和15,20,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:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return buildTree2(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);
}
TreeNode* buildTree2(vector<int> &preorder,vector<int> &inorder,int preStart,int preEnd,int inStart,int inEnd){
if(preStart > preEnd || inStart > inEnd) return NULL;
int root_position = 0;//用于寻找根节点在inorder中的位置
TreeNode *res;
res = new TreeNode(preorder[preStart]);
for(int i = inStart;i <= inEnd;i++){
if(preorder[preStart] == inorder[i]){
root_position = i;
break;
}
}
//root_position - inorder = 左子树的长度,知道这个很容易定出左子树和右子树的范围
res->left = buildTree2(preorder,inorder,preStart+1,preStart + root_position - inStart,inStart,root_position-1);
res->right = buildTree2(preorder,inorder,preStart + root_position - inStart+1,preEnd,root_position+ 1,inEnd);
return res;
}
};