Binary Tree Maximum Path Sum

HardBinary Tree · Post-Order DFS🧩 Tree DFSLeetCode #124 ↗Updated

Problem

A path is a sequence of connected nodes, each used at most once; it may start and end anywhere and need not pass through the root. Given the root of a binary tree, return the largest sum of node values over all non-empty paths.
Input[1,2,3]Output6 (2→1→3)
Input[-10,9,20,null,null,15,7]Output42 (15→20→7)
Input[-3]Output-3

1 ≤ n ≤ 3·104  ·  -1000 ≤ Node.val ≤ 1000

Try it yourself

Java
class Solution {
    public int maxPathSum(TreeNode root) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Every path bends at one top node: val + leftGain + rightGain. But a parent can extend only one branch, so return val + max(leftGain, rightGain) upward — and drop any branch whose gain is negative.
PatternTree DFS

Instinct If the answer for a node can be built from the answers of its left and right subtrees, write one recursive function and trust it on the children.

Memory hack Ask the kids, then decide - each child reports up, the parent combines, and a global variable keeps the best "bend" seen so far.

Open the Tree DFS guide →

Approaches

Brute ForceRecompute Gains at Every Node

Time O(n²)Space O(h)

Try every node as the path's top: its best path is val + max(0, gain(left)) + max(0, gain(right)), where gain = best downward one-branch sum, computed by a fresh DFS. Take the max over all nodes. Gains of deep nodes are recomputed by every ancestor.

Java
public int maxPathSum(TreeNode root) {
    if (root == null) return Integer.MIN_VALUE;
    int through = root.val + Math.max(0, gain(root.left)) + Math.max(0, gain(root.right));
    return Math.max(through, Math.max(maxPathSum(root.left), maxPathSum(root.right)));
}
private int gain(TreeNode node) { // best sum of a path going down from node
    if (node == null) return 0;
    return node.val + Math.max(0, Math.max(gain(node.left), gain(node.right)));
}

Correct by definition, but O(n²) on a skewed tree.

At a glance

LevelApproachTimeSpace
Brute ForceRecompute Gains at Every NodeO(n²)O(h)
BetterMemoized Gains (HashMap)O(n)O(n)
OptimalSingle Post-Order Pass + Global MaxO(n)O(h)
Common pitfalls
  • Returning val + left + right to the parent — a path cannot fork.
  • Starting the answer at 0 — fails for trees with only negative values.
  • Not clamping child gains at 0 — forces a negative branch into the path.
Interview tips
  • Separate the two quantities out loud: best path here vs best gain for parent.
  • Walk through [-10,9,20,null,null,15,7] to show the path skipping the root.
  • Point out it is Diameter of Binary Tree with sums instead of lengths.
Pattern
Post-order DFS with a global best → best path anywhere in a tree; return one-branch value, record two-branch value.
My notes saved in this browser