Leecode热题100-437.路径总和III

看这个之前先看Leetcode面试经典150题-112.路径总和-CSDN博客

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

示例 1:

输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于 8 的路径有 3 条,如图所示。

示例 2:

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

提示:

  • 二叉树的节点个数的范围是 [0,1000]
  • -109 <= Node.val <= 109 
  • -1000 <= targetSum <= 1000 

每行都写注释了,自己看吧,看不懂留言或者私信

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    /**大概思路:记录从根节点开始到目前的前缀和以及各种前缀和出现的次数(map)
    当退出当前节点回到父亲的时候,前缀和减去对应的值,并且在map中减少对应的次数,如果较少完为0的话删除
    当遍历到某个节点的时候看看map里有没有preSum - targetSum,如果有,它有多少个结果就新增多少个*/
    public int pathSum(TreeNode root, int targetSum) {
        /**根据递归方法的含义进行调用,我们要遍历的节点是root, map里只有一个0(因为比如我们targetSum是10,而root也是10,如果不这么放,会遗漏)
        preSum当然是0,因为还没有遍历过*/
        /**千万记得把这个map的key设置为long类型,不然按题目给的条件可能就越界了 */
        HashMap<Long,Integer> map = new HashMap<>();
        /**先放一个0进去 */
        map.put(0l, 1);
        return process(root, map, 0, targetSum);
    }

    /**简单解释一下几个参数:root是我们要遍历的节点,map里存的是之前的前缀和信息,preSum是来到root之前从根开始的前缀和 */
    public int process(TreeNode root, HashMap<Long,Integer> map, long preSum, int targetSum) {
        if(root == null) {
            return 0;
        }
        int ans = 0;
        /**preSum是从根开始到这个节点的前缀和,到了这个节点就加 */
        preSum += root.val;
        /**根据当前节点的值,找一下preSum-targetSum在map里有几个,有几个就加几个到答案里*/
        ans += map.getOrDefault(preSum - targetSum, 0);
        /**当前preSum出现的次数又多了一次(原来有没有都是又多了一次) */
        map.put(preSum, map.getOrDefault(preSum, 0) + 1);
        /**加上左树上可能的次数 */
        ans += process(root.left, map, preSum, targetSum);
        /**加上右树上可能的次数 */
        ans += process(root.right, map, preSum, targetSum);
        /**用完就要回到自己父亲了,要把自己的影响消除 */
        map.put(preSum, map.get(preSum) - 1);
        /**这句可能你理解应该是这样,其实这句不要也无所谓,因为我们这里是值传递,当前preSum+=root.val只是存在于
        当前方法里,出了方法就没有影响了 */
        //preSum -= root.val;
        return ans;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值