
感觉这道题还是有点难,想了半天没想出来直接去看题解了,感觉要反复刷。这道题和之前的560. 和为 K 的子数组很像,对应的博客是这篇,建议先去看前面的博客再来看这道题。这道题更难一些,这道题需要用哈希表来记录符合条件的前缀的个数,除此以外,我们还需要用到回溯的思想,因为我们是根据当前的节点值来向上查找路径个数,当我们在一个左子树中查找完所有符合条件的路径后,还需要到右子树中查找符合条件的路径,但是右子树中的路径的节点与左子树完全不相关,所以我们需要及时回退,将哈希表中关于左子树路径相关的记录删除。感觉这道题的思路还是不太好描述,最好还是结合灵神的题解来看。
cpp
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int pathSum(TreeNode* root, int targetSum) {
int result = 0;
//初始化哈希表,必须这么做
//目的是防止根节点值正好等于targetSum的情况无法被统计
unordered_map<long long, int> Hash{{0, 1}};
//定义递归遍历二叉树的lambda函数
auto dfs = [&](this auto&& dfs, TreeNode* node, long long s){
//递归终止条件
if(!node) return ;
//单层递归主体
s += node -> val;
//将node当作路径的重点,统计起点的数量
result += Hash[s - targetSum]; //如果没有s - targetSum这个键就会新建,且值为0
//回溯
Hash[s]++;
dfs(node -> left, s);
dfs(node -> right, s);
Hash[s]--;
};
dfs(root, 0);
return result;
}
};