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

results matching ""

    No results matching ""