给定一个二叉树的根节点 root
,和一个整数 targetSum
,求该二叉树里节点值之和等于 targetSum
的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
示例 1:
输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于 8 的路径有 3 条,如图所示。
示例 2:
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:3
提示:
二叉树的节点个数的范围是 [0,1000]
−
1
0
9
<
=
N
o
d
e
.
v
a
l
<
=
1
0
9
-10^9 <= Node.val <= 10^9
−109<=Node.val<=109
−
1000
<
=
t
a
r
g
e
t
S
u
m
<
=
1000
-1000 <= targetSum <= 1000
−1000<=targetSum<=1000
解法一:暴力枚举递归
- 枚举从每个节点出发,作为根节点,其路径上有几条路径满足要求
- 对满足要求的路径求和
- 最后返回总路径数
/**
* 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 res = 0;
int pathSum(TreeNode* root, int targetSum) {
dfs(root, targetSum);
return res;
}
void dfs(TreeNode * root, int targetSum){
if(root == nullptr) return;
calPath(root, targetSum - (root -> val));
dfs(root -> left, targetSum);
dfs(root -> right, targetSum);
}
void calPath(TreeNode * u, long long t){
if(t == 0) res++;
if(u -> left != nullptr) calPath(u -> left, t - (u -> left -> val));
if(u -> right != nullptr) calPath(u -> right, t - (u -> right -> val));
}
};
解法二:前缀和
- 从根节点出发,计算每条路径上的前缀和
- 通过 hash 表判断有多少个区间满足,区间总和为 targetSum,即当前路径上满足要求的路径数
- 对所有路径满足的数量求和
- 最终返回对应的结果即可
/**
* 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 res = 0;
unordered_map<long long, int> h;
int pathSum(TreeNode* root, int targetSum) {
h[0] = 1;
dfs(root, 0, targetSum);
return res;
}
void dfs(TreeNode * root, long long pSum, long long targetSum){
if(root == nullptr) return;
pSum += root -> val;
if(h.count(pSum - targetSum)){
res += h[pSum - targetSum];
}
h[pSum]++;
dfs(root -> left, pSum, targetSum);
dfs(root -> right, pSum, targetSum);
h[pSum]--;
}
};