Home
DSA Patterns
Depth-First Search
Path Sum II
Path Sum II
Find all root-to-leaf paths where each path's sum equals the targetSum.
Examples
Two paths sum to 22.
Problem Understanding
Unlike Path Sum I, we need to return every root-to-leaf path whose values add up to targetSum, not just whether one exists.
Since we need the paths themselves, we keep one path list that always holds the nodes from the root down to the current call. When we reach a leaf that completes the sum, we add a copy of path to result.
Algorithm Strategy (Backtracking)
We use DFS with backtracking.
- State: one shared
pathlist, andremaining, what is still needed. - Action: entering a node, append
node.valtopath. - Check: at a leaf whose value is exactly
remaining, save a copy ofpath. - Recurse: otherwise call the left and right children with
remaining - node.val. - Backtrack: pop
node.valoffpathbefore returning, so the parent’s other branch starts from the right path.
Interactive Visualization
The outlined nodes are path itself: a node joins when its call starts and leaves just before its call returns. Each visited node shows what was still needed below it, and a leaf whose path is saved turns green.
Dry Run: [1, 2, 3], Target = 4
Tree: [1, 2, 3], target = 4
| Step | Call | path | Action |
|---|---|---|---|
| 1 | dfs(1, 4) | [1] |
Not a leaf: go left needing 3 |
| 2 | dfs(2, 3) | [1, 2] |
A leaf, but 3 ≠ 2: call both empty children |
| 3 | back in dfs(2) | [1] |
Pop 2 |
| 4 | dfs(3, 3) | [1, 3] |
A leaf and 3 = 3: save [1, 3] |
| 5 | back in dfs(3) | [1] |
Pop 3 |
| 6 | back in dfs(1) | [] |
Pop 1 — return [[1, 3]] |
Edge Cases & Common Mistakes
- Save a copy:
pathis one shared list. Adding it toresultdirectly would leave every entry pointing at the same list, which ends up empty. Addlist(path),new ArrayList<>(path)or[...path]. - Pop in every case: the pop must run after both branches — and also after a saved leaf — or the path keeps nodes that are no longer being visited.
- Negative values: the sum can pass the target and come back, so never stop early just because the running sum is too large.
Solution
Backtracking approach.
Path Sum II Code
1var pathSum = function(root, targetSum) {2 const result = [];3 const path = [];45 function dfs(node, remaining) {6 if (!node) return;7 path.push(node.val);8 if (!node.left && !node.right && remaining === node.val) {9 result.push([...path]);10 } else {11 dfs(node.left, remaining - node.val);12 dfs(node.right, remaining - node.val);13 }14 path.pop();15 }1617 dfs(root, targetSum);18 return result;19};
