【leetcode】437. 路径总和 III

34 阅读1分钟

leetcode-437.png

题目简述:在树中找到连续的路径,使之上面的和等于 targetSum.

在这里思考的也是比较简单,直接带着当前的sum,每次进入递归的时候进行判断
这里的代码没能ac

错误代码

var pathSum = function (root, targetSum) {
    let cnt = 0
    var dfs = function (node, sum) {
        if (!node) return
        sum += node.val
        if (sum === targetSum) {
            cnt++
            // 继续深挖,查看是否还存在符合条件的路径
            dfs(node.left, 0)
            dfs(node.right, 0)
        } else if (sum > targetSum) {
            // 当前的和已经大于 targetSum
            // 那么就从当前的节点重新开始累加
            dfs(node.left, 0)
            dfs(node.right, 0)
        } else {
            // sum < targetSum
            // 继续累加
            dfs(node.left, sum)
            dfs(node.right, sum)
        }
    }
    dfs(root, 0)
    return cnt
};

cannot ac.png

ac

使用preSum来记录路径和出现的次数,用于快速查找是否存在某条路径和为targetSum
preSum[0] = 1表示路径和为0的路径出现了一次

var pathSum = function (root, targetSum) {
    let cnt = 0
    let preSum = new Map()
    preSum.set(0, 1)
    var dfs = function (node, sum) {
        if (!node) return
        sum += node.val
        // 检查是否存在从任意节点到当前节点的路径和为 targetSum
        if (preSum.has(sum - targetSum)) {
            cnt += preSum.get(sum - targetSum)
        }
        // 更新前缀和计数
        preSum.set(sum, (preSum.get(sum) || 0) + 1)
        dfs(node.left, sum)
        dfs(node.right, sum)
        // 回溯
        preSum.set(sum, preSum.get(sum) - 1)
    }
    dfs(root, 0)
    return cnt
};

测试用例计算过程

        10
       /  \
      5   -3
     / \    \
    3   2   11
   / \   \
  3  -2   1
  • 从根节点 10 开始,currSum 为 10,prefixSum 更新为 {0: 1, 10: 1}

  • 移动到左子节点 5currSum 为 15,prefixSum 更新为 {0: 1, 10: 1, 15: 1}

  • 移动到左子节点 3currSum 为 18,找到 prefixSum 中存在 18 - 8 = 10,所以路径 [5, 3] 的和为 8,计数 cnt 增加。

  • 继续遍历并更新 prefixSum,直到整个树遍历完成。