A path in a binary tree is a sequence of nodes where each pair of adjacent nodes has an edge. A path does not need to pass through the root. The path sum is the sum of node values in the path. Return the maximum path sum of any non-empty path.
โข 1 โค number of nodes โค 3 ร 10โดโข -1000 โค Node.val โค 1000
02
Section Two ยท Approach 1
Brute Force โ O(nยฒ)
For every pair of nodes, compute the path sum between them. O(nยฒ) pairs, each requiring O(n) traversal. Far too slow.
03
Section Three ยท Approach 2
Post-Order DFS โ O(n)
At each node, compute the max sum of a path that goes through this node โ possibly using both children (split path). But return to the parent only the best single-branch path (can't split upward). Track a global maximum.
๐ก Mental model: Each node asks its children: "What's the best single-arm path you can offer me?" It then considers three options: (1) just itself, (2) itself + left arm, (3) itself + right arm, (4) itself + both arms (split โ can't go upward). Options 1-3 are reportable to the parent. Option 4 is only used to update the global max.
Algorithm
Recursive function returns the max single-path sum starting from this node going downward.
At each node:
leftGain = max(0, dfs(left)) โ take left branch only if positive.
rightGain = max(0, dfs(right)) โ same for right.
splitPath = node.val + leftGain + rightGain โ path through this node using both sides.
Update globalMax = max(globalMax, splitPath).
Return:node.val + max(leftGain, rightGain) โ best single-arm to offer parent.
๐ฏ Why max(0, ...)?:
If a subtree's best path is negative, don't include it โ it only hurts the sum.
Setting gain to 0 effectively "prunes" that branch. This handles negative values naturally.
Key distinction โ split vs single:
The split path (left + node + right) can be the answer but cannot be extended upward (you can't go left-node-right-parent โ that's not a valid path).
So we only return the best single branch to the parent while updating the global max with the split option.
At each node we do O(1) work โ compare gains, update global max. Total: O(n).
Space is the recursion depth = tree height.
07
Section Seven ยท Edge Cases
Edge Cases & Pitfalls
Case
Input
Why It Matters
All negative
[-3,-2,-1]
Max path is the single largest node (-1). max(0,...) prunes, but globalMax still considers each node alone.
Single node
[5]
Split = 5+0+0 = 5. Correct.
Negative root, positive children
[-10,9,20]
Split through root may be suboptimal. globalMax tracks child paths independently.
โ Common Mistake: Returning the split path (left + node + right) to the parent. A split path through this node uses both branches โ it can't be extended upward because that would create a fork. Only return the best single-arm path: node.val + max(leftGain, rightGain).