一、题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前
序遍历序列{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) {
//特殊情况
//if(pre==null|| in==null || pre.length==0|| in.length)
// return null;
if(pre == null || in == null || pre.length == 0 || in.length == 0){
return null;
}
return buildTree(pre, in, 0, pre.length-1, 0, in.length-1);
}
//构建左子树和右子树
public TreeNode buildTree(int[] pre, int[] in, int preStart, int preEnd, int inStart, int inEnd){
//创建根结点,为前序遍历的第一个结点
TreeNode root = new TreeNode(pre[preStart]);
//找到中序遍历根节点所在位置,存放到gen中
int gen = 0;
for(int i=0;i<in.length;i++){
if(in[i]==root.val){
gen = i;
break;
}
}
int leftLen = gen-inStart;//左子树长度
int rightLen = inEnd-gen;//右子树长度
//递归遍历左子树
if(leftLen>0)
root.left = buildTree(pre, in, preStart+1, preStart+leftLen, inStart, gen-1);
//递归遍历右子树
if(rightLen>0)
root.right = buildTree(pre, in, preStart+leftLen+1, preEnd, gen+1, inEnd);
return root;
}
}