路经总和 III
- 题目规定了寻路方向(不能折返,是单源向下探路,符合DFS)
- 模板1
- 题解1 DFS
- 更好理解题意的版本
- 题解2 前缀和(重点记忆)
- 前缀和 = 由根结点到当前结点的路径上所有节点的和(不含当前结点)
给定一个二叉树的根节点
root
,和一个整数
targetSum
,求该二叉树里节点值之和等于
targetSum
的
路径的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
提示:
- 二叉树的节点个数的范围是 [0,1000]
-
−
1
0
9
-10^9
−109 <=
Node.val
<= 1 0 9 10^9 109 - -1000 <=
targetSum
<= 1000
题目规定了寻路方向(不能折返,是单源向下探路,符合DFS)
模板1
题解1 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 {
int pathnum = 0;
public:
// 题目node.val 可能是9位数,注意long
void dfs(TreeNode* root, long sum){
if(! root) return;
sum -= root->val;
if(0 == sum) pathnum++;
dfs(root->left, sum);
dfs(root->right, sum);
}
int pathSum(TreeNode* root, int targetSum) {
if(! root) return 0;
dfs(root, targetSum);
pathSum(root->left, targetSum);
pathSum(root->right, targetSum);
return pathnum;
}
};
更好理解题意的版本
class Solution {
public:
int dfs(TreeNode* root, long sum){
if(! root) return 0;
int ret = 0;
if(root->val == sum)
ret ++;
ret += dfs(root->left, sum-root->val);
ret += dfs(root->right, sum-root->val);
return ret;
}
int pathSum(TreeNode* root, int targetSum) {
if(! root) return 0;
// 以当前结点为起点,递归向下搜索
int ret = dfs(root, targetSum);
// 单源——以所有结点为源,找完可能的路径
ret += pathSum(root->left, targetSum);
ret += pathSum(root->right, targetSum);
return ret;
}
};
题解2 前缀和(重点记忆)
前缀和 = 由根结点到当前结点的路径上所有节点的和(不含当前结点)
class Solution {
unordered_map<long, int> prefixSum;
public:
int dfs(TreeNode* root, long sum, int targetSum){
if(! root) return 0;
int ret = 0;
// 当前结点对应的前缀和
sum += root->val;
// 以当前节点为尾结点的某个前缀和存在 == 有满足条件的路径
if(prefixSum.count(sum - targetSum)){
ret = prefixSum[sum - targetSum];
}
// 保存当前结点往下搜索
prefixSum[sum] ++;
ret += dfs(root->left, sum, targetSum);
ret += dfs(root->right, sum, targetSum);
// 回溯:退出当前结点
prefixSum[sum] --;
return ret;
}
int pathSum(TreeNode* root, int targetSum) {
// 因为用的是减法,避免sum = targetSum时为0
prefixSum[0] = 1;
return dfs(root, 0, targetSum);
}
};