[LeetCode] 437. Path Sum Ⅲ(路径和之三)

Description

You are given a binary tree in which each node contains an integer value.
给定一棵二叉树,每个节点包含一个整数

Find the number of paths that sum to a given value.
找到路径和为给定值的路径的个数

The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
路径不要求必须始于根终于节点,但一定要是往下走的(只允许从父节点到子节点这个方向)

The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
树的节点数不超过 1,000,节点值在 -1,000,000 到 1,000,000 之间。

Example

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

      10
     /  
    5   -3
   /     
  3   2   11
 /    
3  -2   1

Return 3. The paths that sum to 8 are:

1.  5 -> 3
2.  5 -> 2 -> 1
3. -3 -> 11

Solution

一个简单的 DFS 方法,代码如下:

/**
 * Example:
 * var ti = TreeNode(5)
 * var v = ti.`val`
 * Definition for a binary tree node.
 * class TreeNode(var `val`: Int) {
 *     var left: TreeNode? = null
 *     var right: TreeNode? = null
 * }
 */
class Solution {
    fun pathSum(root: TreeNode?, sum: Int): Int {
        if (root == null) {
            return 0
        }
        //     以这个节点为 root 开始找
        return pathSumRecursive(root, sum) +
        //      以左右子树为 root 开始找
                pathSum(root.left, sum) +
                pathSum(root.right, sum)
    }

    private fun pathSumRecursive(root: TreeNode?, target: Int): Int {
        if (root == null) {
            return 0
        }
        //     由于树的节点有正有负,所以你不能简单判定到 target 了就退出递归
        return (if (root.`val` == target) 1 else 0) +
                pathSumRecursive(root.left, target - root.`val`) +
                pathSumRecursive(root.right, target - root.`val`)
    }
}

另一个方法来自 discussion,利用了哈希表存储前缀和,key 为前缀和,value 为到达前缀和的路径的个数,代码如下:

class Solution {
    fun pathSum(root: TreeNode?, sum: Int): Int {
        val preSum = hashMapOf(0 to 1)
        return helper(root, 0, sum, preSum)
    }

    fun helper(root: TreeNode?, currSum: Int, target: Int, preSum: MutableMap<Int, Int>): Int {
        var currSum = currSum
        if (root == null) {
            return 0
        }
        currSum += root.`val`
        var res = preSum.getOrDefault(currSum - target, 0)
        preSum[currSum] = preSum.getOrDefault(currSum, 0) + 1
        res += helper(root.left, currSum, target, preSum) + helper(root.right, currSum, target, preSum)
        preSum[currSum] = preSum.getValue(currSum) - 1
        return res
    }
}
原文地址:https://www.cnblogs.com/zhongju/p/14014916.html