LeetCode 437 路径总和 III


1. 题目

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

LeetCode 437  路径总和 III_当前路径

2. 解题思路

  • 朴素求解

两趟DFS,第一趟DFS为遍历每个节点,并将该节点作为根节点传入DFS2中,如果该根节点到某个节点的路径和为taregetSum,则为目标路径

  • DFS+前缀和

朴素求解是从顶点到叶子顶点计算的,此问题我们将其看作为从顶部开始的前缀和,如果某个非顶节点的路径和为sum,那么如果前缀和数组中如果map[sum-target]存在,则代表该路径中存在目标路径,因此我们采用一个dict存储当前的前缀和,通过dfs遍历每个节点,判断当前节点的map[sum-target]即可。

3. 代码

  • 朴素求解

    
    class Solution:
        def __init__(self):
            self.res=0
        def pathSum(self, root: TreeNode, targetSum: int) -> int:
            def dfs1(tree):
                if not tree:
                    return
                dfs2(tree,tree.val)
                dfs1(tree.left)
                dfs1(tree.right)
            def dfs2(tree,val):
                if val==targetSum:
                    self.res+=1
                if tree.left!=None:
                    dfs2(tree.left,val+tree.left.val)
                if tree.right!=None:
                    dfs2(tree.right,val+tree.right.val)
            dfs1(root)
            return self.res
    
  • DFS+前缀和

    class Solution:
        def __init__(self):
            self.res=0
            #初始化dict
            self.map=Counter([0])
            self.target=0
        def pathSum(self, root: TreeNode, targetSum: int) -> int:
            self.target=targetSum
            def dfs(tree,cur):
                if not tree:
                    return 0
                #计算当前路径和
                cur+=tree.val
                #ans表示当前路径中存在目标路径的数量
                #map为前缀和
                ans=self.map[cur-targetSum]
                #更新前缀和数组
                self.map[cur]+=1
                if tree.left:
                    ans+=dfs(tree.left,cur)
                if tree.right:
                    ans+=dfs(tree.right,cur)
                self.map[cur]-=1
                return ans
            return dfs(root,0)