1
+ from collections import Counter
2
+
3
+ class Solution (object ):
4
+ def pathSum (self , root , sum ):
5
+ def helper (node , sum_from_root , record ):
6
+ sum_from_root += node .val
7
+ sum_to_p = sum_from_root - sum
8
+ self .ans += record [sum_to_p ]
9
+
10
+ record [sum_from_root ] += 1 #1
11
+ if node .left :
12
+ helper (node .left , sum_from_root , record )
13
+ if node .right :
14
+ helper (node .right , sum_from_root , record )
15
+ record [sum_from_root ] -= 1 #2
16
+
17
+ self .ans = 0
18
+ if not root : return self .ans
19
+ record = Counter ()
20
+ record [0 ] = 1 #3
21
+ helper (root , 0 , record )
22
+ return self .ans
23
+
24
+ """
25
+ This answer is inspired by @gabbu
26
+ Some variable and function:
27
+ 1. `self.ans` stores the number of paths that sum to a given value.
28
+ 2. `helper()` will traverse the tree and increase `self.ans` along the way.
29
+ 3. `sum_from_root` is the sum from the `node` to the `root`. Note that, there maybe multiple ways to get to a node.
30
+ 4. `record` is the number of ways that paths sums up to a number. In short, `record[any_sum]` you get **number of ways to have any_sum**.
31
+
32
+ 0.
33
+ `record` is the hardest part to understand, you need to see the main idea below first.
34
+ Imagine we are now at a node in the tree, N. The sum of the path from root to N (including `N.val`) is `sum_from_root`.
35
+ Imagine a predecessor of N, we call it P. The sum of the path root->P (including N.val) is `sum_to_p`. Given a node N, there maybe multiple or no P.
36
+ `sum_to_p + sum(P->N) == sum_from_root`, thus `sum(P->N) == sum_from_root - sum_to_p`
37
+ This problem we are looking for **the number of ways P->N, where `sum == sum(P->N)`** (where `sum == sum_from_root - sum_to_p`).
38
+ Thus, we are basically looking for the number of ways root->P, where `sum_to_p == sum_from_root - sum`.
39
+ So that is why we have `record`. We can find the number of ways root->P by record[sum_to_p] (record[sum_from_root - sum]).
40
+
41
+ 1.
42
+ Maintain the `record`.
43
+
44
+ 2.
45
+ Remove the case from the `record` after all the children are done calculating.
46
+ This prevent other node counts the irerlevant `record`.
47
+
48
+ Time complexity is O(N). Since we only traverse each node once.
49
+ Space complexity O(N). Since in the worst case, we might go N-level of recursion.
50
+ """
0 commit comments