Path Sum III
Given the roottargetSumtargetSum
Example 1
Output: 3
Explanation: The three paths are: 5→3, 5→2→1, and -3→11. Each sums to 8.
Example 2
Output: 3
Constraints:
0 <= Number of nodes <= 1000-109 <= Node.val <= 109-1000 <= targetSum <= 1000
Solution: Prefix Sum with HashMap
The key insight mirrors the "subarray sum equals K" array problem. As we traverse from root to
a node, we maintain a running prefixSumprefixSum - targetSumtargetSum
We store each prefix sum's frequency in a HashMap{0: 1}
Algorithm:
- Initialize
andprefixCount = {0: 1} .prefixSum = 0 - At each node, add its value to
.prefixSum - Look up
in the map: that count is added to the result.prefixSum - targetSum - Increment the count of
in the map.prefixSum - Recurse on left and right children.
- Backtrack: decrement the count of
before returning.prefixSum
public int pathSum(TreeNode root, int targetSum) {
Map<Long, Integer> prefixCount = new HashMap<>();
prefixCount.put(0L, 1); // base case: empty path
return dfs(root, 0L, targetSum, prefixCount);
}
private int dfs(TreeNode node, long prefixSum, int target,
Map<Long, Integer> prefixCount) {
if (node == null) return 0;
prefixSum += node.val;
// how many times (prefixSum - target) appeared earlier on this path
int count = prefixCount.getOrDefault(prefixSum - target, 0);
// record current prefix sum
prefixCount.merge(prefixSum, 1, Integer::sum);
count += dfs(node.left, prefixSum, target, prefixCount);
count += dfs(node.right, prefixSum, target, prefixCount);
// backtrack — remove current prefix sum contribution
prefixCount.merge(prefixSum, -1, Integer::sum);
return count;
}
Note: Use longprefixSum
Complexity Analysis
- Time: O(n). Each node is visited exactly once; HashMap operations are O(1) average.
- Space: O(n). The HashMap stores at most O(h) entries at any point (h = tree height), but O(n) in total across the full traversal due to backtracking. Recursion stack is O(h).