题目:
给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
算法:
方法一:
暴力+DFS
主要要划分好条件和子函数。
搜索的路径包括root节点:rootSum(root)
搜搜的路径不包括root节点:pathSum(root.Left)+pathSum(root.Right)
func pathSum(root *TreeNode, targetSum int) int {
if root == nil {
return 0
}
return rootSum(root, targetSum) + pathSum(root.Left, targetSum) + pathSum(root.Right, targetSum)
}
func rootSum(root *TreeNode, targetSum int) int {
if root == nil {
return 0
}
sum := 0
if root.Val == targetSum {
sum ++
}
sum = sum + rootSum(root.Left, targetSum - root.Val) + rootSum(root.Right, targetSum - root.Val)
return sum
}
方法二
回溯+前缀和
数和数组的路径和都可以转换为前缀和
func pathSum(root *TreeNode, targetSum int) int {
prefixSumMap := make(map[int]int)
// 【 不需要从根节点开始,也不需要在叶子节点结束】 一个节点都不选的选择有一个
prefixSumMap[0] = 1
return doPathSum(root, prefixSumMap, 0, targetSum)
}
func doPathSum(root *TreeNode, prefixSumMap map[int]int, curPrefixSum, targetSum int) int {
if root == nil {
return 0
}
curPrefixSum = curPrefixSum + root.Val
sum := prefixSumMap[curPrefixSum - targetSum]
prefixSumMap[curPrefixSum] ++
left := doPathSum(root.Left, prefixSumMap, curPrefixSum, targetSum)
right := doPathSum(root.Right, prefixSumMap, curPrefixSum, targetSum)
prefixSumMap[curPrefixSum] --
return sum + left + right
}