题目:
给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
示例:
输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于8 的路径有 3 条,如图所示。
思路:
使用递归进行先序遍历,初始化路径条数是0,字典中放的是不同的前缀和作为键,对应的值是这个前缀和出现的次数。进入递归调用函数,当节点非空时,累加前缀和加上当前节点的值,然后累加路径次数。
这里注意,用当前前缀和减去目标值的结果如果能在字典中找到,说明有成立的路径,加在路径次数里,如果没有就默认为0,但是当前缀和正好等于目标值时说明有路径,所以在字典中包括了0:1这一组键值对,同时要将当前前缀和键对应的值加1,然后递归调用当前节点的左右子树,找到合适的路径。
调用完以后要将前缀和的次数减去1,因为路径必须是从上到下的,这两个节点必须一个节点是另一个节点的祖先节点,所以对于不是祖先节点的情况要恢复到原来的状态。
比如示例中的二叉树,传入根节点10,然后左右子树进行递归找合适的路径,先递归完左子树再递归右子树,那么左子树递归完,应该将加上左子树根节点5的前缀和在字典中的值减去1,恢复到原来的状态,因为下一个就是遍历右子树,而节点5肯定不能算在里面,因为它不是右子树某个节点的祖先,这样的路径不符合要求,所以要将状态恢复。
累加次数的过程,要找到前缀和减去目标值的数出现的次数加进结果里,而不是直接加1,因为这个数可能不止一次,比如当有0节点出现时,所以对于前缀和出现的次数也要累加。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def pathSum(self, root, targetSum):
"""
:type root: TreeNode
:type targetSum: int
:rtype: int
"""
self.count = 0
dict1 = {0:1}
def dfs(root,target,pathsum,dict1):
if root:
pathsum += root.val
self.count += dict1.get(pathsum - target,0)
dict1[pathsum] = dict1.get(pathsum,0) + 1
dfs(root.left,target,pathsum,dict1)
dfs(root.right,target,pathsum,dict1)
dict1[pathsum] -= 1
dfs(root,targetSum,0,dict1)
return self.count