刷刷刷 Day 18 | 路径总和

文章介绍了LeetCode上的两道关于二叉树路径总和的问题,分别是寻找单一路径总和等于目标和以及找出所有路径总和等于目标和的路径。解题方法主要采用前序遍历和递归,通过不断调整目标和并检查是否到达叶子节点来判断条件。在路径总和II问题中,需使用回溯来获取所有符合条件的路径。
摘要由CSDN通过智能技术生成
112. 路径总和
LeetCode题目要求

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
叶子节点 是指没有子节点的节点。

图

示例

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。
解题思路

本地要计算的事从根节点到叶子节点路径的和是否符合targetSum,是不是想到了之前的 257. 二叉树的所有路径 这个题,那么是不是可以对这个题稍作修改,找到所有路径后来计算他们的和是否符合 targetSum。其实这样做的话,并不是太优,因为我们要找到所有路径。而本题其实只要找到其中一个符合的就可以,也就是不需要遍历出所有的路径。
那么本题可以采用前序遍历的方式,并不断的用 targetSum 减去节点值,当差为 0 且节点为叶子节点时就找到了

上代码

class Solution {
    public boolean hasPathSum(TreeNode node, int targetSum) {
        if (node == null) {
            return false;
        }

        targetSum -= node.val;

        // 叶子节点路径的和是否符合 targetSum
        if (node.left == null && node.right == null) {
            return targetSum == 0;
        }

        // 处理左子树,如果和符合 targetSum, 返回true
        if (node.left != null) {
            if (hasPathSum(node.left, targetSum)) {
                return true;
            }
        }

        // 处理右子树,如果和符合 targetSum, 返回true
        if (node.right != null) {
            if (hasPathSum(node.right, targetSum)) {
                return true;
            }
        }

        return false;
    }
}
重难点

前序遍历,递归,回溯。 这里回溯实际是隐藏了起来。可以通过 debug 模式来自己理解下


113. 路径总和 II
LeetCode题目要求

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。

图

示例

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
解题思路

本题类似于 112. 路径总和。稍微复杂的是需要所有的路径,其实这个题可以采用这个题 257. 二叉树的所有路径 ,找到所有路径后来计算他们的和是否符合 targetSum,把符合的都输出就是结果了。

上代码

class Solution {

    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> res = new ArrayList<>();

        List<Integer> paths = new ArrayList<>();
        traversal(root, targetSum, res, paths);

        return res;
    }

    private void traversal(TreeNode node, int targetSum, List<List<Integer>> res, List<Integer> paths) {
        if (node == null) {
            return;
        } 

        //前序遍历,先是中节点
        paths.add(node.val);

        // 是否叶子节点
        if (node.left == null && node.right == null) {
            // 如果符合目标值,需要将值放入到 结果集,由于需要找到过个路径,这里不能变化 targetSum 的值
            if (targetSum - node.val == 0) {
                res.add(new ArrayList<>(paths));
            }
            return;
        }

        if (node.left != null) {
            // 由于需要找到过个路径,这里不能变化 targetSum 的值
            traversal(node.left, targetSum - node.val, res, paths);
            // 回溯
            paths.remove(paths.size() - 1);
        }

        if (node.right != null) {
            // 由于需要找到过个路径,这里不能变化 targetSum 的值
            traversal(node.right, targetSum - node.val, res, paths);
            // 回溯
            paths.remove(paths.size() - 1);
        }
    }
}
重难点

前序遍历,递归,回溯。递归不需要返回值

附:学习资料链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值