LeetCode105: Construct Binary Tree from Preorder and Inorder Traversal

37 篇文章 0 订阅
26 篇文章 0 订阅

这里写图片描述
与题目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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值