题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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) {
return ConstructTree(pre,in,0,pre.length-1,0,in.length-1);
}
public TreeNode ConstructTree(int [] pre,int [] in,int pStart,int pEnd,int iStart,int iEnd) {
TreeNode treeNode = new TreeNode(pre[pStart]);
int nBoot = 0; //当前子树序列的根节点在中序遍历中的位置
int leftCount = 0;//当前子树的左子树节点个数
int rightCount = 0;//当前子树的右子树节点个数
for(int i = iStart;i<=iEnd;i++) { //找到当前子树根节点在中序遍历中的位置
if(in[i] == pre[pStart]) {
nBoot = i;break;
}
leftCount++;
}
rightCount = pEnd - pStart - leftCount + 1 - 1; //当前子树先序遍历尾节点位置-当前子树先序遍历首节点位+1(首尾都要计算)-左子树个数-当前子树根节点个数(1)
if(pre[pStart] != in[iStart]) {//当前子树有左子树
treeNode.left = ConstructTree(pre,in,pStart+1,pStart+1+leftCount,iStart,nBoot-1);
}
if(pre[pStart] != in[iEnd]) {//当前子树有右子树
treeNode.right = ConstructTree(pre,in,pEnd-rightCount+1,pEnd,nBoot+1,iEnd);
}
return treeNode;
}
}