代码随想录算法训练营第十八天 | 513.找树左下角的值 & 112. 路径总和 & 106.从中序与后序遍历序列构造二叉树

1. 找树左下角的值

513. 找树左下角的值 - 力扣(LeetCode)

前面学的层序遍历,用队列实现

右子树先入列,左子树后入列

这样就能保证最后一行的最左边是最后一个出列的

lass Solution {
    public int findBottomLeftValue(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        int res = 0;
        queue.offer(root);
        while(!queue.isEmpty()){
            TreeNode temp = queue.poll();
            if(temp.right != null)
                queue.offer(temp.right);
            if(temp.left != null)
                queue.offer(temp.left);
            res = temp.val;
        }
        return res;
    }   
}

2. 路径总和

112. 路径总和 - 力扣(LeetCode)

递归实现

一层一层的往下减去当前值

直到找到叶子节点,判断结果是否为0

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null) return false;
        if(root.left == null && root.right == null && targetSum - root.val == 0) return true;
        boolean hasLeft = hasPathSum(root.left, targetSum - root.val);
        boolean hasRight = hasPathSum(root.right, targetSum - root.val);
        return hasLeft || hasRight;
    }
}

3. 从中序与后序遍历序列构造二叉树

106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

postorder的最后一个元素是树的root

这个元素在inorder中,它的前面是左子树,后面是右子树(的中序排序)

而根据左子树的节点数量又可以在postorder中划分出左右子树(的后序排序)

这样根据子树的中序和后序排序,又可以找到子树的根节点,以及子树的左右子树

递归,即可将root和子节点连接

后序排序的最后一个元素是root

根据root在中序排序中找到左右子树的中序排序

再找出左右子树的后序排序

如此往复

class Solution {
    Map<Integer, Integer> map; 
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置
            map.put(inorder[i], i);
        }
        return deal(inorder,0,inorder.length, postorder,0,postorder.length);
    }

    public TreeNode deal(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd){
        if(inBegin >= inEnd || postBegin >= postEnd) return null;
        int rootValue = postorder[postEnd-1];
        TreeNode mid = new TreeNode(rootValue);
        int index_inorder = map.get(rootValue);//inorder中, mid的下标
        int lenOfLeft = index_inorder - inBegin; //左子树节点个数

        mid.left = deal(inorder,inBegin,index_inorder, 
                        postorder, postBegin, postBegin+ index_inorder-inBegin);
        mid.right = deal(inorder,index_inorder+1,inEnd, 
                        postorder, postBegin+index_inorder-inBegin, postEnd-1);
        return mid;
    }
}

思路都是一样的,就是上面的感觉有点绕

我又写了一份用 Arrays.copyOfRange() 来划分区间

class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if(postorder.length == 0) return null;
        int rootValue = postorder[postorder.length-1];
        TreeNode root = new TreeNode(rootValue);
        
        int index_root_inorder = 0;//inorder中, root的下标
        for(int i =0; i<inorder.length; i++){
            if(inorder[i] == rootValue){
                index_root_inorder = i;
                break;
            }
        }

        int[] left_inorder = Arrays.copyOfRange(inorder, 0, index_root_inorder);
        int[] right_inorder = Arrays.copyOfRange(inorder, index_root_inorder + 1, inorder.length);

        int[] left_postorder = Arrays.copyOfRange(postorder,0, left_inorder.length);
        int[] right_postorder = Arrays.copyOfRange(postorder, left_postorder.length, postorder.length - 1);

        root.left = buildTree(left_inorder, left_postorder);
        root.right = buildTree(right_inorder, right_postorder);
        return root;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值