输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路: 按中序遍历,为根节点,在前(后)序中找该结点,并分为四个部分 左子树的 前,中;右子树 的先 中序。
两种实现风格:
1、利用下标,截取vector区间;(空间复杂度低)
2、直接重新构建子vector,进行下次迭代传参。
(1) 2 4 5。。。
4 7 2(1) 前面有三个数,所以上面那个先序的也要选3个作为左子树的 先序序列
即:
2 4 5
4 7 2
```c++
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
TreeNode *root=reTree(pre,0,pre.size()-1,vin,0,vin.size()-1);
return root;
}
TreeNode* reTree(vector<int> pre,int sp,int ep,vector<int> vin,int sin,int ein) {
if(sp>ep||sin>ein)
return NULL;
TreeNode* root=new TreeNode(pre[sp]);
/*int i=sin;
while(vin[i]!=pre[sp])// find id in vin
i++;
root->left=reTree(pre,sp+1,sp+i-sin,vin,sin,i-1);
// 左子树节点个数 i-sin ,也是在先序前面的 i-sin个
root->right=reTree(pre, sp+i-sin+1, ep,vin,i+1 ,ein);
*/
for(int i=sin;i<=ein;++i){// find id in vin
if(vin[i]==pre[sp]){
root->left=reTree(pre,sp+1,sp+i-sin,vin,sin,i-1);
// 左子树节点个数 i-sin ,也是在先序前面的 i-sin个
root->right=reTree(pre, sp+i-sin+1, ep,vin,i+1 ,ein);
break;
}
}
return root;
}
};
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
/* class Solution {
public:
struct TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> in){
if (pre.size() == NULL)
return NULL;
TreeNode* root = new TreeNode(pre[0]);
int i ;
for (i = 0; i < in.size() && in[i] != pre[0]; i++);
vector<int> pre_left, in_left,pre_right,in_right;
int pre_i = 1;
for (int j = 0; j < in.size(); j++){
if (j < i){
in_left.push_back(in[j]);
pre_left.push_back(pre[pre_i]);
pre_i++;
}
else if (j>i){
in_right.push_back(in[j]);
pre_right.push_back(pre[pre_i]);
pre_i++;
}
}
root->left = reConstructBinaryTree(pre_left, in_left);
root->right = reConstructBinaryTree(pre_right, in_right);
return root;
}
};*/
```