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
Add the prefix sum to the hashMap, and check along path if hashMap.contains(pathSum+cur.val-target);
My Solution
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 public class Solution { 11 public int pathSum(TreeNode root, int sum) { 12 if (root == null) return 0; 13 ArrayList<Integer> res = new ArrayList<Integer>(); 14 res.add(0); 15 HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); 16 map.put(0, 1); 17 helper(root, sum, 0, res, map); 18 return res.get(0); 19 } 20 21 public void helper(TreeNode cur, int target, int pathSum, ArrayList<Integer> res, HashMap<Integer, Integer> map) { 22 if (map.containsKey(pathSum+cur.val-target)) { 23 res.set(0, res.get(0) + map.get(pathSum+cur.val-target)); 24 } 25 if (!map.containsKey(pathSum+cur.val)) { 26 map.put(pathSum+cur.val, 1); 27 } 28 else map.put(pathSum+cur.val, map.get(pathSum+cur.val)+1); 29 if (cur.left != null) helper(cur.left, target, pathSum+cur.val, res, map); 30 if (cur.right != null) helper(cur.right, target, pathSum+cur.val, res, map); 31 map.put(pathSum+cur.val, map.get(pathSum+cur.val)-1); 32 } 33 }
一个更简洁的solution: using HashMap to store ( key : the prefix sum, value : how many ways get to this prefix sum) , and whenever reach a node, we check if prefix sum - target exists in hashmap or not, if it does, we added up the ways of prefix sum - target into res.
1 public int pathSum(TreeNode root, int sum) { 2 Map<Integer, Integer> map = new HashMap<>(); 3 map.put(0, 1); //Default sum = 0 has one count 4 return backtrack(root, 0, sum, map); 5 } 6 //BackTrack one pass 7 public int backtrack(TreeNode root, int sum, int target, Map<Integer, Integer> map){ 8 if(root == null) 9 return 0; 10 sum += root.val; 11 int res = map.getOrDefault(sum - target, 0); //See if there is a subarray sum equals to target 12 map.put(sum, map.getOrDefault(sum, 0)+1); 13 //Extend to left and right child 14 res += backtrack(root.left, sum, target, map) + backtrack(root.right, sum, target, map); 15 map.put(sum, map.get(sum)-1); //Remove the current node so it wont affect other path 16 return res; 17 }