Description
You are given a binary tree in which each node contains an integer value.
Find the number of paths that sum to a given value.
The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
Example
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
Return 3. The paths that sum to 8 are:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
Solution 1(C++)
static int x=[](){std::ios::sync_with_stdio(false); cin.tie(NULL); return 0;}();
class Solution {
public:
int fsum=0;
int NumCount(TreeNode* node, int sum){
if(!node) return 0;
return (node->val==sum?1:0)+NumCount(node->left, sum-node->val)+NumCount(node->right, sum-node->val);
}
int pathSum(TreeNode* root, int sum) {
fsum=sum;
if(!root) return NumCount(root, sum);
else return NumCount(root, sum)+pathSum(root->right, sum)+pathSum(root->left, sum);
}
};
Solution 2(C++)
class Solution {
unordered_map<int, int> kv{{0,1}};
public:
int pathSum(TreeNode* root, int sum) {
return rec(root, 0, sum);
}
int rec(TreeNode* root, int csum, int targ) {
if (!root) return 0;
csum+=root->val;
kv[csum] += 1;
int lc = rec(root->left, csum, targ);
int rc = rec(root->right, csum, targ);
kv[csum] -= 1;
return kv[csum-targ] + lc + rc;
}
};
算法分析
解法一是自己做的,中规中矩了,只是喜欢用迭代的话,可以参考这次的答案。
解法二是最快解法。解法二从形式上看是深度优先,逻辑上来说,解法二用hash表记录当前结点到根节点所有路径经过节点权值之和,也就是csum,注意,csum是根节点到当前子节点的,比如:
x1->x2->x3->x4->x5
当前节点是x5,那么x1,x1+x2,x1+x2+x3,x1+x2+x3+x4都被记录在hash表中了,记为s1,s2,s3,s4,假如说x2+x3就是sum,那么s3-sum=s1,s1就应该记录在表中。
那如果sum=s5呢,s5并没有记录在表中,但是当前路径的和csum=s5,这时csum-sum=0,而hash表一开始初始化时就有{0,1}。问题解决。
这就是解法二的核心思想。观察到子路径的和可以由总路径转换而来,从而方便解决了问题。转化的思路也是非常重要的。
后续更新啦,遇到类似思想的问题,可参考:LeetCode-560. Subarray Sum Equals K。
程序分析
略。’