Reference: LeetCode Difficulty: Medium
Problem
Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum equals the given sum.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Given: the below binary tree and sum = 22 , 5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1 Output: [ [5 ,4 ,11 ,2 ], [5 ,8 ,4 ,5 ] ]
Analysis Methods:
Recursion (Preorder traversal)
Time: $O(N + Lh)$ where $L$ is the number of valid paths. 1 ms
Visiting all nodes take $O(N)$.
Creating $L$ valid paths, each one takes $h$ time to create.
Space: $O(h + Lh) = O(Lh)$
Note: We can make a new copy of list in each function call, but it takes a lot of space.
Iteration
I tried preorder
, inorder
, bfs
. All of them are difficult to implement because of the timing of recovering the path
list.
Finally, I add a map depthMap
to record the depth of each node. Time: $O(N + Lh)$. And recovering the path list takes time. 6 ms
Space: $O(N)$
Code Recursion Note:
Remember to recover the path.
Learn the way to make a new copy of list.
Be careful of the generic type:
Correct: LinkedList<List<Integer>> result = new LinkedList<>();
Incorrect: LinkedList<LinkedList<Integer>> result = new LinkedList<>();
The return type is List<List<Integer>>
, which is not compatible with LinkedList<LinkedList<Integer>>
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public List<List<Integer>> pathSum (TreeNode root, int sum) { LinkedList<Integer> path = new LinkedList <>(); LinkedList<List<Integer>> result = new LinkedList <>(); pathSum(root, sum, path, result); return result; } private void pathSum (TreeNode root, int sum, LinkedList<Integer> path, LinkedList<List<Integer>> result) { if (root == null ) { return ; } path.addLast(root.val); if (root.left == null && root.right == null ) { if (root.val == sum) { result.add(new LinkedList (path)); } } else { pathSum(root.left, sum - root.val, path, result); pathSum(root.right, sum - root.val, path, result); } path.removeLast(); }
Iteration Note:
The order! Push into stack the right child first.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public List<List<Integer>> pathSum (TreeNode root, int sum) { LinkedList<Integer> path = new LinkedList <>(); LinkedList<List<Integer>> result = new LinkedList <>(); HashMap<TreeNode, Integer> depthMap = new HashMap <>(); if (root == null ) { return result; } Stack<TreeNode> stack = new Stack <>(); Stack<Integer> sums = new Stack <>(); stack.push(root); depthMap.put(root, 1 ); sums.push(sum); while (stack.size() > 0 ) { TreeNode p = stack.pop(); int depth = depthMap.get(p); int s = sums.pop(); path.addLast(p.val); if (p.left == null && p.right == null ) { if (p.val == s) result.add(new LinkedList <>(path)); } if (p.right != null ) { stack.push(p.right); depthMap.put(p.right, depth + 1 ); sums.push(s - p.val); } if (p.left != null ) { stack.push(p.left); depthMap.put(p.left, depth + 1 ); sums.push(s - p.val); } if (stack.size() > 0 ) { int d = depthMap.get(stack.peek()); while (path.size() > d - 1 ) { path.removeLast(); } } } return result; }