
/**
求和为指定值的路径条数,且由上自下遍历
前缀和 + hashmap:
遍历二叉树的同时,计算每个节点对应的前缀和
判断哈希表中存在几个值为 当前前缀和 - target 的元素 有几个即为几条路径 同560.和为k的子数组
将当前 前缀和添加到哈希表中(查询前添加 避免当前前缀影响结果)
递归遍历 左子树 与右子树
不涉及到对根节点的处理 遍历顺序无所谓
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//避免重复传参
private int targetSum;
//记录符合条件的路径数
private int res;
//哈希表 preSum - count 前缀和以及出现次数
private Map<Long,Integer> hash = new HashMap<>();
public int pathSum(TreeNode root, int targetSum) {
/**
求和为指定值的路径条数,且由上自下遍历
前缀和 + hashmap:
遍历二叉树的同时,计算每个节点对应的前缀和
判断哈希表中存在几个值为 当前前缀和 - target 的元素 有几个即为几条路径 同560.和为k的子数组
将当前 前缀和添加到哈希表中(查询前添加 避免当前前缀影响结果)
递归遍历 左子树 与右子树
不涉及到对根节点的处理 遍历顺序无所谓
*/
//初始化
hash.put(0L,1);
this.targetSum = targetSum;
countPathSum(root,0L);
return res;
}
private void countPathSum(TreeNode root,Long sum) {
if(root == null) {
return;
}
//计算当前前缀
sum += root.val;
//判断哈希表中存在几个值为 当前前缀和 - target 的元素 有几个即为几条路径
if(hash.containsKey(sum - targetSum)) {
res += hash.get(sum - targetSum);
}
//记录当前 前缀和 出现过则++ 第一次出现则设为1
hash.put(sum,hash.getOrDefault(sum,0) + 1);
//递归遍历左 右子树
countPathSum(root.left,sum);
countPathSum(root.right,sum);
//回溯:移除当前前缀和(避免影响其他分支)
hash.put(sum, hash.get(sum) - 1);
if (hash.get(sum) == 0) {
hash.remove(sum); // 完全移除计数为0的键
}
}
}
266

被折叠的 条评论
为什么被折叠?



