InterviewPrepKit

Home / Coding / Trees

Binary Tree Maximum Path Sum

hard Original ↗
Solving tips
  • Key framing: every path has a unique highest node (its peak), an inverted V climbing from the left arm through the peak into the right arm.
  • One post-order DFS: return each node's best single downward arm (node.val + max(left, right)) to the parent, but update a global best with node.val + left + right (both arms) at the peak.
  • Clamp each arm with max(0, gain): a negative subtree should contribute nothing, and this is the whole trick.
  • Initialize best to -inf (not 0) so an all-negative tree returns a negative single node; target O(n) time and O(h) space.

Problem

A path in a binary tree is any sequence of nodes in which each consecutive pair is joined by an edge, and no node appears more than once. A path can start and end at any nodes in the tree — it does not have to pass through the root, and it does not have to reach a leaf. The path sum is the sum of the values of the nodes on the path.

Given the root of a binary tree, return the maximum path sum over all possible non-empty paths.

Note that node values may be negative, so the best path might be a single node.

Examples

Example 1

    1
   / \
  2   3

Input: root = [1,2,3] → Output: 6 The best path is 2 → 1 → 3 with sum 2 + 1 + 3 = 6.

Example 2

   -10
   /  \
  9    20
      /  \
     15   7

Input: root = [-10,9,20,null,null,15,7] → Output: 42 The best path is 15 → 20 → 7 with sum 42; going up through -10 would only hurt.

Example 3

Input: root = [-3] → Output: -3 The path must be non-empty, so with a single negative node the answer is that node’s value.

Constraints

  • The tree has between 1 and 3 × 10⁴ nodes — an O(n²) scan per node is too slow; aim for O(n).
  • -1000 <= Node.val <= 1000 — values can be negative, so “take everything” never works.

Think about it first

Hint 1 Any path has a highest node — its "peak". Seen from that peak, the path looks like an inverted V: it climbs up from somewhere in the left subtree, passes through the peak, and descends into the right subtree (either arm may be empty).
Hint 2 If you knew, for every node, the best sum of a path that starts at that node and only goes downward, then the best path peaking at node `x` is `x.val + bestDown(x.left) + bestDown(x.right)` — where a negative arm should be replaced by 0 (just don't take it).
Hint 3 Compute those downward gains in a single post-order DFS. Each call returns `node.val + max(0, leftGain, rightGain)` to its parent (a parent can extend only one arm), and along the way updates a global best with `node.val + max(0, leftGain) + max(0, rightGain)` (the peak may use both arms).
Your workspace Not runnable by design — this is your interview scratchpad. Saved on this device.