题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
牛客网给出的准备代码如下:
/**
* 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) {
}
}
作者:Monotone
链接https://www.nowcoder.com/questionTerminal/8a19cbe657394eeaac2f6ea9b0f6fcf6
来源:牛客网
递归思想,每次将左右两颗子树当成新的子树进行处理,中序的左右子树索引很好找,前序的开始结束索引通过计算中序中左右子树的大小来计算,然后递归求解,直到startPre>endPre||startIn>endIn说明子树整理完到。方法每次返回左子树活右子树的根节点
下面是我结合理解,给出的解释。
思想:这道题运用到了递归方法。首先,要知道前序遍历和中序遍历结果倒推二叉树的步骤(可以看我的这篇文章前序遍历、中序遍历、后序遍历)。主要步骤就是,先确定根结点,再确定左结点和右结点。这个就是需要我们递归的步骤。那么在题目中,确定根结点是很好确定的,但是左结点和右节点就有难度,因为左右都是子树而不是叶子结点。那么我们就把左右子树都重新当成新的树来处理,重复上述步骤(确定根结点,在确定左、右结点)。
/**
* 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) {
TreeNode tree = reConstruct(pre,0,pre.length-1,in,0,in.length-1);
return tree;
}
public TreeNode reConstruct(int[] pre,int startPre,int endPre,int[] in,int startIn,int endIn){
if(startPre>endPre || startIn>endIn){//递归结束的条件
return null;
}
TreeNode root = new TreeNode(pre[startPre]);//每次将根结点确定
for(int i=startIn;i<=endIn;i++){
if(in[i] == pre[startPre]){//找到根结点在中序遍历结果数组的位置
//在中序遍历结果中找到根结点后root后,以root为分界线,分为左子树的值集合和右子树的值集合(因为在中序遍历结果中,根结点的左边属于它的左子树里的值,右边属于它的右子树里的值)
root.left = reConstruct(pre,startPre+1,startPre+i,in,startIn,i-1);
root.right = reConstruct(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
break;
}
}
return root;
}
}