题目描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解题思路:以前序序列的第一个值为分界线,拆分中序遍历序列为左子树中序遍历序列,和右子树中序遍历序列,在以拆分后的左子树中序遍历序列和右子树中序遍历序列,拆分前序遍历序列为左子树的前序遍历序列和右子树的前序遍历序列,最终返回生成树即可。
代码如下:
/**
* 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) {
if(pre.size()==0)
return NULL;//判断当前遍历序列是否为空,若为空则建立空节点
TreeNode *root=(TreeNode*)malloc(sizeof(TreeNode));//为当前序列建立子树
root->val=pre[0];//以前序序列第一个值作为子树的根节点
vector<int>preLeft;
vector<int>preRight;
vector<int>vinLeft;
vector<int>vinRight;
int sum=0,mark=0;
for(int i=0;i<pre.size();i++)//以前序序列首值为分界线,拆分中序序列,左边为该子树的左子树中序遍历,右边为该子树的右子树中序遍历序列
{
if(vin[i]!=pre[0]&&!mark)
{
vinLeft.push_back(vin[i]);
sum++;
}
if(mark)
vinRight.push_back(vin[i]);
if(vin[i]==pre[0])
mark=1;
}
for(int j=0;j<pre.size()-1;j++)//以拆分后的中序遍历序列拆分前序遍历
{
if(j<sum)
preLeft.push_back(pre[1+j]);
else
preRight.push_back(pre[1+j]);
}
root->left=reConstructBinaryTree(preLeft,vinLeft);//建立当前子树的左子树和右子树
root->right=reConstructBinaryTree(preRight,vinRight);
return root;//返回当前序列的生成子树
}
};