算法刷题Day16 - 二叉树Part4|513.找二叉树左下角的值|112.路径总和|113.路径总和II|106.从中序后序遍历构造二叉树

LeetCode - 513. Find Bottom Left Tree Value 找二叉树左下角的值

解题目标:找出二叉树最后一行最左边的值

解题思路:这道题的关键在于终止条件也就是遍历到叶子节点,判断当前深度是否是最大的,注意应当优先搜索左边的子树,如果先搜索右边子树,但实际左下角的值是存在于左子树中,那么结果就有可能停留在右子树了。

class Solution {
    int maxDepth = Integer.MIN_VALUE;
    int res = 0;

    public int findBottomLeftValue(TreeNode root) {
        traversal(root, 0);
        return res;
    }

    public void traversal (TreeNode root, int curDepth) {
        if (root.left == null && root.right == null) {
            if (curDepth > maxDepth) {
                maxDepth = curDepth;
                res = root.val;
            }
        }
        // left
        if (root.left != null) {
            traversal(root.left, curDepth + 1);
        }
        // right
        if (root.right != null) {
            traversal(root.right, curDepth + 1);
        }
    }
}

LeetCode - 112. Path Sum 路径总和

解题目标:给定一个二叉树和目标和,判断该树是否存在叶子节点到根节点的路径和等于目标和。

解题思路:递归题目先确定终止条件,终止条件除了根节点为空,其次就是叶子节点,在叶子节点判断叶子节点的值是否是targetSum,如果是的话就返回true。在询问左子树或右子树前先要用targetSum减去当前根节点的值,这样才能继续递归左子树或右子树,只要左或右能有一条是true即可。

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) {
            return false;
        }
        // leaf node
        if (root.left == null && root.right == null) {
            return targetSum == root.val;
        }
        targetSum -= root.val;
        if (root.left != null) {
            if (hasPathSum(root.left, targetSum)) return true;
        }
        if (root.right != null) {
            if (hasPathSum(root.right, targetSum)) return true;
        }
        return false;
    }
}

LeetCode - 113. Path Sum II 路径总和 II

解题目标:给定一个二叉树和目标和,记录该树所有叶子节点到根节点的路径和等于目标和的情况。

解题思路:这道题和前一题类似,只不过最终要记录所有的path,因此需要一个helper function来帮助记录最终结果。这里注意在收集结果时path需要创建新对象来拷贝,因为path在回溯的时候是会变化的,如果不拷贝最后只有最后找到的一条路径。同时注意这里的targetSum在遍历左右子树前其实已经是隐式回溯了,因为这里减去root.val是传递给左或右子树的参数的,当前层需要用到targetSum的情况已经在这之前判断过了,因此不用显式地在遍历完左右子树后加回root.val来体现回溯。

class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        findPaths(root, res, path, targetSum);
        return res;
    }

    public void findPaths(TreeNode root, List<List<Integer>> res, List<Integer> path, int targetSum) {
        if (root == null) return;
        path.add(root.val);
        if (root.left == null && root.right == null) {
            if (root.val == targetSum) {
                res.add(new ArrayList<>(path)); //需要拷贝当前路径,否则在回溯的时候会被修改
            }
            return;
        }
        targetSum -= root.val;
        if (root.left != null) {
            findPaths(root.left, res, path, targetSum);
            path.remove(path.size() - 1);
        }
        if (root.right != null) {
            findPaths(root.right, res, path, targetSum);
            path.remove(path.size() - 1);
        }
    }
}

LeetCode - 106. Construct Binary Tree from Inorder and Postorder Traversal

解题思路:这道题可以从后序数组开始切入,后序的最后一个元素一定是该树的根节点,知道了根节点后可以在中序当中做切割,这样就可以分清哪些元素是左子树,哪些是右子树。知道了左右如何分割左右子树后,再回到后序数组按照中序数组切割后就可以找到左/右子树的根节点,再继续这样循环往复就可以构造出二叉树。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值