## 437. Path Sum III (top-to-down, find path for target)

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
``````

Thoughts:

1. DFS recursion: T: O(N^2)

1. Find the root.left and root.right: (base case: for root == null; return 0)
2. if (both left and right ==0)-> leaf node, then return 1,
3. if only left == 0: have to return right + 1
4. if only right == 0; have to return left + 1
5. if both left and right != 0; then return the min(left,right) + 1
6. Merge sort : T: T(N) = N + 2T(N/2) = O(NlogN) or O(N^2) for worse complexity (unbalanced tree)
2. Two Sum Method: Hash table: T: O(n) S: O(n):

1. As we traverse down the tree, at an arbitrary node N, we store the sum until this node N (sum_so_far (prefix) + N.val). in hash-table. Note this sum is the sum from root to N.
2. Now at a grand-child of N, say G, we can compute the sum from the root until G since we have the prefix_sum until this grandchild available.We pass in our recursive routine.
3. Search for prefixSum + node.val - target for the predecessor
4. Once done with a node and all its grandchildren, we remove it from the hash-table. This makes sure that the number of complement paths returned always correspond to paths that ended(started) at a predecessor node.

Code: DFS Recursion O(N^2)

``````/**
* Definition for a binary tree node.
* public class TreeNode {
*     int val;
*     TreeNode left;
*     TreeNode right;
*     TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int pathSum(TreeNode root, int sum) {
if(root == null) return 0;
int left = pathSum(root.left, sum);
int right = pathSum(root.right, sum);
return left + right + pathSumStart(root, sum);
// wrong:
// int left = pathSum(root.left, sum) + pathSum(root.left, sum - root.val);
// int right = pathSum(root.right, sum) + pathSum(root.right, sum - root.val);
// System.out.println(root.val  + " " +  sum + " " + left + " " + right );
// return left + right + (root.val == sum ?1:0);
}
private int pathSumStart(TreeNode node, int sum){
if(node == null) return 0;
return (node.val == sum ?1:0)
+ pathSumStart(node.left, sum - node.val)
+ pathSumStart(node.right, sum - node.val);
}
}
``````

Code: Python

``````# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
def find_paths(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: int
"""
if root:
return int(root.val == sum) + self.find_paths(root.left, sum - root.val) + self.find_paths(root.right, sum - root.val)

return 0

def pathSum(self, root, sum):

if root:
return self.find_paths(root, sum) + self.pathSum(root.left, sum) + self.pathSum(root.right, sum)

return 0
``````

Code: Two-Sum: HashTable: T: O(n) S: O(n)

``````# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
def helper(self,root, target, preS, path):
if root:
key = preS + root.val - target
if key in path:
self.result += path[key]
path.setdefault(preS + root.val, 0) # if not found, set to 0
path[preS + root.val] +=1
self.helper(root.left, target, preS+root.val, path)
self.helper(root.right, target, preS+root.val, path)
# remove predecessor from the record
path[preS + root.val] -=1
return

def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: int
"""
self.result = 0
self.helper(root,sum,0, {0:1})
return self.result
``````