剑指offer 专项突破版 50、向下的路径节点之和

题目链接

  • 这道题的本质和我们此前做的10、和为 k 的子数组一样,所以可以用前缀和来解决
  • 但是前缀和不能等到全都遍历完了,在叶结点计算,因为这样会产生重复计算的问题,所以需要边遍历边计算
  • 每次dfs函数需要把上一个元素的前缀和传入,这样方便我们计算本次的前缀和
  • 注意map是shallow-copy 所以子函数会对map产生影响,这样可能会影响父函数对于个数的判断,因此我们在dfs函数结束前要加一句
sums.put(sum, sums.get(sum) - 1);

这样会把该结点的前缀和从map中移除,所以就不会对父函数查表产生影响

class Solution {
    public int pathSum(TreeNode root, int targetSum) {
        int[] time = new int[]{0};
        Map<Integer, Integer> sums = new HashMap<>();
        sums.put(0, 1);

        dfs(root, 0, sums, time, targetSum);

        return time[0];
    }

    private void dfs(TreeNode root, int sum, Map<Integer, Integer> sums, int[] time, int target) {

        if (null == root)
            return;

        sum += root.val;
        time[0] += sums.getOrDefault(sum - target, 0);
        sums.put(sum, sums.getOrDefault(sum, 0) + 1);

        dfs(root.left, sum, sums, time, target);
        dfs(root.right, sum, sums, time, target);

        sums.put(sum, sums.get(sum) - 1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值