主页有其他数据结构内容(持续更新中)
难度:Medium
代码:
法一:双重递归,经典DFS
/**
* 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:
long long count = 0;
void dfs(TreeNode* root, long long sum) {
if (root == nullptr) {
return;
}
sum -= root->val;
if (sum == 0) {
count++;
// 这里不需要return,因为不要求在叶结点结束,所以一条路径下方可能还有其他路径
}
dfs(root->left, sum);
dfs(root->right, sum);
}
long long pathSum(TreeNode* root, long long targetSum) {
if (root == nullptr) {
return 0;
}
// 以root为起始点开始搜索路径
dfs(root, targetSum);
// 左子树递归
pathSum(root->left, targetSum);
// 右子树递归
pathSum(root->right, targetSum);
return count;
}
};
法二:前缀和
/**
* 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 {
private:
unordered_map<long long, int> dic; // <前缀和,其出现次数>
int res = 0; // 满足条件的路径数量
void dfs(TreeNode* root, long long targetSum, long long cur_sum)
{
if (root == nullptr) {
return;
}
cur_sum += root->val; // 更新前缀和
// 当前路径中存在以当前节点为终点的和为sum的子路径
if (dic.find(cur_sum - targetSum) != dic.end())
res += dic[cur_sum - targetSum];
dic[cur_sum]++; // 将当前节点加入路径
dfs(root->left, targetSum, cur_sum); // 在其左子树中递归寻找
dfs(root->right, targetSum, cur_sum); // 在其右子树中递归寻找
dic[cur_sum]--; // 回溯,必须要将当前的前缀和出现次数减1
}
public:
int pathSum(TreeNode* root, long long targetSum)
{
dic[0] = 1; // 前缀和为0的路径只有一条:哪个节点都不选
dfs(root, targetSum, 0); // 第三个参数传入0,表示当前的前缀和为0
return res;
}
};