1. 程式人生 > 實用技巧 >[LeetCode] 437. Path Sum Ⅲ(路徑和之三)

[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
    }
}