题目描述
给定一个二叉树的根节点 root
,和一个整数 targetSum
,求该二叉树里节点值之和等于 targetSum
的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
示例 1:
1 2 3
| 输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8 输出:3 解释:和等于 8 的路径有 3 条,如图所示。
|
示例 2:
1 2
| 输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22 输出:3
|
提示:
- 二叉树的节点个数的范围是
[0,1000]
-10^9 <= Node.val <= 10^9
-1000 <= targetSum <= 1000
解法
- 前缀和+深度优先搜索
- 记录下根节点 root到当前节点 p的路径上除当前节点以外所有节点的前缀和
- 在已保存的路径前缀和中查找是否存在前缀和刚好等于当前节点到根节点的前缀和
currentSum
减去 targetSum
- 对于空路径我们也需要保存预先处理一下
- 当我们退出当前节点时,我们需要及时更新已经保存的前缀和,不能让自底向上过程受到影响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class Solution {
public int pathSum(TreeNode root, int targetSum) { Map<Long,Integer> prefix=new HashMap<>(); prefix.put(0L, 1); return dfs(root, prefix, 0, targetSum); }
public int dfs(TreeNode node, Map<Long,Integer> prefix,long currentSum,int targetSum){ if (node==null){ return 0; } int res=0; currentSum+=node.val;
res=prefix.getOrDefault(currentSum-targetSum, 0); prefix.put(currentSum, prefix.getOrDefault(currentSum, 0)+1); res+=dfs(node.left, prefix, currentSum, targetSum); res+=dfs(node.right, prefix, currentSum, targetSum); prefix.put(currentSum, prefix.getOrDefault(currentSum, 0)-1);
return res; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution { int cnt=0; public int pathSum(TreeNode root, int targetSum) { if (root==null){ return 0; } rootSum(root,targetSum); pathSum(root.left,targetSum); pathSum(root.right,targetSum); return cnt; }
private void rootSum(TreeNode root, long targetSum) { if (root==null){ return; } int val=root.val; if (val==targetSum){ cnt++; } rootSum(root.left, targetSum-val); rootSum(root.right, targetSum-val); } }
|
来源:力扣(LeetCode)
链接:437. 路径总和 III - 力扣(LeetCode)