Day18_BT, Leetcode 513, 112&113, and 106

Leetcode 513:

https://leetcode.com/problems/find-bottom-left-tree-value/description/

题目的第一想法:

这道题我的直觉是做层序遍历,然后记录下每层的第一个值然后返回。做完是可以成立的。写法如下

class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Deque<TreeNode> q = new LinkedList<>();
        int rvalue = 0;
        q.add(root);
        while(!q.isEmpty()){
            int size = q.size();
            boolean first = true;
            while(size > 0){
                TreeNode temp = q.poll();
                if(temp.left != null){
                    q.offer(temp.left);
                }
                if(temp.right != null){
                    q.offer(temp.right);
                }
                if(first){
                    rvalue = temp.val;
                    first = false;
                }
                size--;
            }
        }
        return rvalue;
    }
}

看完代码随想录之后的想法:

这道题还有一个更快的解法,是做一个正常的遍历然后记录最深层的数据。这样的话时间复杂度一样,但空间复杂度可以变得更少(如果层序遍历使用了queue来记录当前层的Node的话)。

Leetcode 112&113:

https://leetcode.com/problems/path-sum/

https://leetcode.com/problems/path-sum-ii/

题目的第一想法:

112这题我最一开始的想法就是递归,然后条件是如果为root为null且targetSum为0就返回true不然就递归fun(root.left, targetSum - root.val) || fun(targetSum - root.right)。但这样写有一个问题。即无法处理当一个node只有左或只有右node时的情况,因为递归会走到null然后返回,和判断树最小高度的问题很类似。因此,我们在这种情况做一个判断leaf的条件会比直接依靠null来判断要好很多。以下为112的写法

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

接下来说一说113,这道题比起112要稍微复杂一些,因为我们需要记录下所有路径的值。那么在什么时候加入又在什么时候剔除list里面的值就变成了一个问题。这个问题大体的写法是遍历所有的node,然后沿途加入当前node的数值。最后当targetSum为0时把list内的值加入到rlists里面去。那么何时可以加入何时剔除数值呢。我最一开始的想法是,在当前层加入,然后在上一层剔除。很可惜这是不可能实现的,因为我们不可避免的会进入root为null的情况里。此时,我们是无法加入任何数值进去,而上一层总会剔除一个值。所以我们会不可避免的多剔除一个数值。所以我们需要当前层剔除当前层加入的数值。如此,我们才能保证加入的数值可以被正确的剔除。写法如下

class Solution {
    List<List<Integer>> rlists = new LinkedList<>();
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        Deque<Integer> list = new LinkedList<>();
        pathSum(root, targetSum, list);
        return rlists;
    }

    public void pathSum(TreeNode root, int targetSum, Deque<Integer> list){
        if(root == null){
            return;
        }else if(root.left == null && root.right == null && targetSum - root.val == 0){
            list.add(root.val);
            rlists.add(new LinkedList<Integer>(list));
            list.pollLast();
            return;
        }else if(root.left == null && root.right == null){
            return;
        }
        list.add(root.val);
        pathSum(root.left, targetSum - root.val, list);
        pathSum(root.right, targetSum - root.val, list);
        list.pollLast();
    }
}

Leetcode 106:

https://leetcode.com/problems/find-bottom-left-tree-value/description/

题目的第一想法:

这道题没什么第一想法。感觉脑子并没能第一时间整理出一个规整的走法出来。

看完代码随想录之后的想法:

我觉得这个算法还是挺难自己想出来的。大概有几个需要注意的点,一是起点和终点不能一样。因为终点会--。其次leftover(因为index是从0开始算的,假设leftover有三个,start+leftover就是3)本身就多了一个,所以当起点时不需要再+1了。

class Solution {
    HashMap<Integer, Integer> hash = new HashMap<>();
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for(int i = 0; i < inorder.length; i++){
            hash.put(inorder[i], i);
        }
        TreeNode root = buildTree(inorder, 0, inorder.length, postorder, 0, postorder.length);
        return root;
    }

    public TreeNode buildTree(int[] inorder, int instart, int inend, int[] postorder, int postart, int poend){
        if(instart >= inend || postart >= poend){
            return null;
        }
        int rootin = hash.get(postorder[poend - 1]);
        TreeNode root = new TreeNode(postorder[poend - 1]);
        int leftover = rootin - instart;
        root.left = buildTree(inorder, instart, rootin, postorder, postart, postart + leftover);
        root.right = buildTree(inorder, rootin + 1, inend, postorder, postart + leftover, poend - 1);
        return root;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值