105.根据一棵树的先序遍历与中序遍历构造二叉树(力扣)

解题思路:

依次取出先序遍历的每个节点,取出的第一个结点 A,一定是根节点;

再取出第二个节点 B,此时不能确定 B 是 A 的左子树还是右子树,需要看中序遍历;

在中序遍历中,如果 B 在 A 的左侧,那么 B 就是 A 的左子树,如果 B 在 A 的右侧,那么 B 就是 A 的右子树;

以此类推

// 成员变量,index 表示当前访问到 先序 中的第几个元素
    public int index = 0;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        // 由于输入的用例可能有多组,所以在方法入口这里把 index 还原成 0,防止多个用例之间干扰
        index = 0;
        // 辅助递归方法中后两个参数表示当前这个子树对应的中序遍历结果
        // 使用这一对下标表示当前子树的中序遍历结果是在 inorder 的那个部分上
        return _buildTree(preorder, inorder,0,inorder.length);
    }
    // [inorderLeft, inorderRight) 标注了一个前闭后开的区间
    // inorder 数组上的这个区间中的内容, 就正是当前子树的中序遍历结果
    public TreeNode _buildTree(int[] preorder, int[] inorder,
                               int inorderLeft, int inorderRight) {
        if(inorderLeft>inorderRight){
            //中序区间是一个空区间,说明当前子树是空树
            return null;
        }
        if (index >= preorder.length) {
            //先序结果遍历完毕,整个树就处理完了
            return null;
        }
        //处理一般情况,仍然是进行先序遍历
        //访问结点操作不是打印,而是构建结点
        TreeNode root = new TreeNode(preorder[index]);
        //查找当前结点在中序区间中所处的位置
        int pos = find(inorder,inorderLeft,inorderRight,root.val);
        //有了 pos 之后,就知道了当前结点左右子树的中序区间
        //左子树的中序区间:[inorderLeft,pos)
        //右子树的中序区间:(pos+1,inorderRight]
        //递归处理左右子树
        //此处 index 只 ++ 一次
        //如果遍历结果中有空节点,就要 ++ 两次
        //如果没有空节点,只 ++ 一次
        index++;
        root.left = _buildTree(preorder, inorder, inorderLeft, pos);
        root.right = _buildTree(preorder, inorder, pos+1, inorderRight);
        return root;
    }
    private int find(int[] array, int left, int right, int toFind) {
        for(int i=left;i<right;i++){
            if(array[i]==toFind){
                return i;
            }
        }
        return -1;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值