题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路:前序遍历第一个节点就是根节点,根节点在中序遍历中将数分为两组,左边是左子树,右边是右子树,分别将左子树和右子树分别进行寻找根节点,递归实现。
1.java版
整个过程最难的是判断左子树的前序遍历的右边界,根据“左子树的长度”在前序和中序遍历中相等的原则,?-1-prestart是前序遍历中左子树的长度,那么中序遍历中左子树的长度是index-1-instart,即可推出?=index-instart+prestart;哈哈,到这里就非常的清晰了。
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre==null||in==null||pre.length!=in.length||pre.length<=0)
{
return null;
}
TreeNode node=construct(pre,0,pre.length-1,in,0,in.length-1);
return node;
}
private TreeNode construct(int [] pre,int prestart,int preend,int []in,int instart,int inend)
{
if(prestart>preend||instart>inend)
return null;
int val=pre[prestart];
TreeNode node=new TreeNode(val);
node.val=val;
for(int index=instart;index<=inend;index++)
{
if(in[index]==node.val)
{
node.left=construct(pre,prestart+1,prestart+index-instart,in,instart,index-1);
node.right=construct(pre,prestart+index-instart+1,preend,in,index+1,inend);
}
}
return node;
}
}
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) {
if(pre.size()<=0||vin.size()<=0||pre.size()!=vin.size())
return nullptr;
vector<int> left_pre,right_pre,left_vin,right_vin;
TreeNode *head=new TreeNode(pre[0]);
int gen=0;
for(int i=0;i<vin.size();i++)
{
if(vin[i]==pre[0])
{
gen=i;
break;
}
}
for(int i=0;i<gen;i++)
{
left_vin.push_back(vin[i]);
left_pre.push_back(pre[i+1]);
}
for(int i=gen+1;i<vin.size();i++)
{
right_vin.push_back(vin[i]);
right_pre.push_back(pre[i]);
}
head->left=reConstructBinaryTree(left_pre,left_vin);
head->right=reConstructBinaryTree(right_pre,right_vin);
return head;
}
};