[LeetCode] 437. Path Sum Ⅲ(路径和之三)
-
Difficulty: Medium
-
Related Topics: Tree
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
}
}