时间复杂度:O(n)
解题思路
用前缀和哈希表记录下各个前缀和的出现次数,先序遍历二叉树,每遍历到一个结点,就更新前缀和,并且查找前缀和哈希表中当前前缀和与目标值的差的前缀和出现次数,及时更新路径总和结果。并且将前缀和哈希表中当前前缀和的出现次数加1,当遍历完孩子结点后再回溯减1,保证路径是从上到下的。
为什么要查找前缀和哈希表中当前前缀和与目标值的差的前缀和出现次数呢?理由就是,如果存在一个前缀和满足二者之差这个条件,那么就说明有一条路径满足到当前根节点的路径和为目标值。所以只要统计当前前缀和与目标值的差的前缀和出现次数,就知道有多少条路径可以实现到当前根节点的路径和为目标值。
AC代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func pathSum(root *TreeNode, targetSum int) (res int) {
pathSum:=map[int]int{0:1}//必须对前缀和哈希表初始化
var preOrder func(*TreeNode,int)
preOrder=func(root *TreeNode,sum int){
if root==nil{
return
}
sum+=root.Val//sum为算上该结点值的前缀和
res+=pathSum[sum-targetSum]
pathSum[sum]++
preOrder(root.Left,sum)
preOrder(root.Right,sum)
pathSum[sum]--//回溯,保证路径方向
}
preOrder(root,0)
return res
}
感悟
前缀和,听上去很高大上,实际就是记录下每个路径和的出现次数,然后根据与目标值的关系查找出现的次数。