与题目106类似:
从前序遍历,与中序遍历中还原二叉树。
假设树:
通过先序遍历找到第一个点作为根节点,在中序遍历中找到根节点并记录index。
因为中序遍历中根节点左边为左子树,所以可以记录左子树的长度(index-in_left),并在先序遍历中依据这个长度找到左子树的区间,用同样方法可以找到右子树的区间。
递归的建立好左子树和右子树即可。
public class Solution {
/**
*pre_left pre_right表示前序遍历在数组中的左右
* in_left in_right 中序遍历在数组中的左右
*/
public TreeNode reConstruct(int[] preorder, int[] inorder,int pre_left,int pre_right,int in_left,int in_right){
if(preorder==null || inorder==null || pre_left>pre_right || in_left > in_right) return null;
if(preorder.length==1){
TreeNode root = new TreeNode(preorder[0]);
return root;
}
int len=0;
TreeNode root = new TreeNode(preorder[pre_left]);
int index = findIndex(inorder,preorder[pre_left],in_left,in_right);
len = index-in_left;//记录左子树长度
//递归建立左右子树
root.left = reConstruct(preorder,inorder,pre_left+1,pre_left+len,in_left,index-1);//[pre_left+1,pre_left+len]左子树在前序遍历数组中的区间,[in_left,index-1]左子树在中序遍历数组中的区间
root.right = reConstruct(preorder,inorder,pre_left+len+1,pre_right,index+1,in_right);
//[pre_left+len+1,pre_right]右子树在前序遍历数组中的区间,[index+1,in_right]右子树在中序遍历数组中的区间
// [pre_left+1,pre_left+len]左子树在前序遍历数组中的区间与[pre_left+len+1,pre_right]右子树在前序遍历数组中的区间形成一个闭区间
//[in_left,index-1]左子树在中序遍历数组中的区间与[index+1,in_right]右子树在中序遍历数组中的区间形成一个闭区间
return root;
}
//从中序遍历中找到根节点
public int findIndex(int[] inorder,int num,int begin,int end){
int index=0;
for(int i=begin;i<=end;i++){
if(num == inorder[i]){
index=i;
break;
}
}
return index;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
TreeNode root = reConstruct(preorder,inorder,0,preorder.length-1,0,inorder.length-1);
return root;
}
}