路径总和 III:树上的前缀和
418 字
2 分钟
路径总和 III:树上的前缀和
核心结论
从根到当前节点的前缀和为 currentSum。如果祖先路径中出现过 currentSum - targetSum,从该祖先之后到当前节点的路径和就等于目标值。用哈希表记录当前递归路径上的前缀和次数,可以在线性时间内计数。
前缀和关系
路径不必从根开始,但方向必须从父节点向子节点。假设祖先节点之前的前缀和是 previousSum:
currentSum - previousSum = targetSum
previousSum = currentSum - targetSum
前缀和可能超出 int 范围,因此累加值使用 long。
Java 实现
class Solution {
public int pathSum(TreeNode root, int targetSum) {
Map<Long, Integer> prefixCounts = new HashMap<>();
prefixCounts.put(0L, 1);
return countPaths(root, 0L, targetSum, prefixCounts);
}
private int countPaths(
TreeNode node,
long currentSum,
int targetSum,
Map<Long, Integer> prefixCounts
) {
if (node == null) {
return 0;
}
currentSum += node.val;
int count = prefixCounts.getOrDefault(currentSum - targetSum, 0);
prefixCounts.merge(currentSum, 1, Integer::sum);
count += countPaths(node.left, currentSum, targetSum, prefixCounts);
count += countPaths(node.right, currentSum, targetSum, prefixCounts);
prefixCounts.merge(currentSum, -1, Integer::sum);
return count;
}
}
为什么需要回溯
哈希表只能描述从根到当前节点的这一条路径。离开节点时必须撤销它的前缀和,否则左子树的状态会错误地参与右子树计数,形成并不存在的跨分支路径。
正确性与复杂度
每个合法路径对应一对前缀和,其差为 targetSum;哈希表记录次数,因此重复前缀和也不会漏计。每个节点进入和退出各一次,平均时间复杂度为 O(n),空间复杂度为 O(h) 到 O(n)。
验证
覆盖空树、负数、零、重复前缀和、目标路径从根开始,以及目标路径位于非根子树的情况。
参考
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
路径总和 III:树上的前缀和
https://blog.mintalix.com/posts/study-pathsumiii/相关文章智能推荐
1
二叉树中序遍历:递归与显式栈
algorithms从左、根、右的访问顺序出发,实现二叉树中序遍历,并比较递归与显式栈两种写法的边界和复杂度。
2
最小路径和:压缩二维动态规划
algorithms从只能向右或向下移动的约束推导最小路径和状态转移,并将二维状态表压缩为一维数组。
3
最小路径和:二维动态规划基础解法
algorithms使用二维动态规划记录到达每个网格的最小代价,讲清边界初始化、状态转移与复杂度。
4
被围绕的区域:从边界反向搜索
algorithms从边界上的 O 出发标记所有不可填充区域,再统一翻转剩余单元格,避免逐区域判断边界连通性。
5
最大正方形:用相邻状态确定边长
algorithms定义以当前单元格为右下角的最大正方形边长,推导三邻居状态转移,并给出 Java 动态规划实现。
随机文章随机推荐


