根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
输出:
3
/ \
9 20
/ \
15 7
思路:递归构建二叉树,先序遍历的顺序是根,左,右。中序遍历的顺序是左,根,右。
所以我们只需要根据先序遍历得到根节点,然后在中序遍历中找到根节点的位置,它的左边就是左子树的节点,右边就是右子树的节点。
算法流程:
1.从前序遍历查找第一个节点作为根节点,然后在中序遍历中找到该节点,记下索引位置。
2.根据该索引将中序遍历的数组分为左右两个数组,分别表示左子树的中序遍历和右子树的中序遍历。
3.再利用该索引将前序遍历的数组分为左右两份,大致同上
4.将左前序遍历数组,左中序遍历数组作为参数递归进入下一层构建左子树
5.同上构建右子树
6.返回根节点
public TreeNode buildTree(int[] preorder, int[] inorder) {
return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
public TreeNode build(int[] preorder,int start,int end,int[] inorder,int left,int right){
//left,right表示中序遍历的边界 start,end表示前序遍历的边界
//返回条件,中序遍历中没有值,说明没有值,返回null
if(left>right)
return null;
//从前序遍历查找第一个节点
TreeNode root=new TreeNode(preorder[start]);
//中序遍历找出对应的根节点
int mid=0;
for(int i=left;i<=right;i++){
if(root.val==inorder[i]){
mid=i;
break;
}
}
//将中序遍历划分为左右两个序列
//在递归进入该节点的左右子节点
//leftnum表示该节点的左子树中有几个节点
int leftnum=mid-left;
root.left=build(preorder,start+1,start+leftnum,inorder,left,mid-1);
root.right=build(preorder,start+leftnum+1,end,inorder,mid+1,right);
return root;
}