#124 Binary Tree Maximum Path Sum
frequently reported atAdobeAmazonByteDance / TikTokSalesforceMetaMicrosoft
the problem
In plain words
A path is a sequence of nodes connected by edges, each node used at most once; it doesn't need to pass the root. Return the maximum sum of node values on any non-empty path.
in root = [1,2,3]
out 6
2 → 1 → 3.
in root = [-10,9,20,null,null,15,7]
out 42
15 → 20 → 7.
- 1 ≤ number of nodes ≤ 3·10⁴
- -1000 ≤ Node.val ≤ 1000
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
LeetCode-style: complete the class. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
patternTree DFS (bottom-up)Kadane / running best
Same shape as Diameter: return the best one-sided downward path (the parent can only extend one side), record the best two-sided bend. Drop any side whose gain is negative.
solutions
From brute force to optimal
For each node, compute the best downward path from each child with a fresh DFS, and try node + both gains.
- down(n) = n.val + max(0, down(left), down(right)).
- For every node: node.val + max(0, down(left)) + max(0, down(right)).
down() re-walks whole subtrees for every node (a skewed tree costs n + (n−1) + …).
Recursion and the explicit stack.
class Solution { public int maxPathSum(TreeNode root) { int best = Integer.MIN_VALUE; Deque<TreeNode> stack = new ArrayDeque<>(); stack.push(root); while (!stack.isEmpty()) { // try every node as the path's top TreeNode node = stack.pop(); int peak = node.val + Math.max(0, down(node.left)) + Math.max(0, down(node.right)); best = Math.max(best, peak); if (node.left != null) stack.push(node.left); if (node.right != null) stack.push(node.right); } return best; } /** Best sum of a path that starts at node and only goes downwards (fresh walk every call). */ private int down(TreeNode node) { if (node == null) return 0; return node.val + Math.max(0, Math.max(down(node.left), down(node.right))); }}gain(node) returns node.val + the better non-negative child gain, and records node.val + both gains.
- best = Integer.MIN_VALUE.
- left = max(0, gain(left)), right = max(0, gain(right)).
- best = max(best, node.val + left + right).
- Return node.val + max(left, right).
Each node visited once.
Recursion stack.
class Solution { private int best; public int maxPathSum(TreeNode root) { best = Integer.MIN_VALUE; // values can be negative: never start at 0 gain(root); return best; } /** Best downward path starting at node; also records the best path that bends at node. */ private int gain(TreeNode node) { if (node == null) return 0; int left = Math.max(0, gain(node.left)); // a negative branch is worse than none int right = Math.max(0, gain(node.right)); best = Math.max(best, node.val + left + right); // path bending here uses both sides return node.val + Math.max(left, right); // parent can extend only ONE side }}Dry run
in the room
How to say it in the interview
talk track
- Say: "This is Diameter with values instead of edge counts."
- Explain clamping at 0: a negative branch is worse than not taking it — the same "restart" choice as Kadane's algorithm.
- Explain why the return value uses only one side: a path can't fork.
traps
- Initializing best to 0 — an all-negative tree like [-3] must return −3.
- Returning node.val + left + right to the parent — that would make the path fork.
what they ask next
Follow-ups
Return the path itself?
Return the gain and remember which child gave it; at the best node, stitch left arm (reversed) + node + right arm.
before you submit
Edge cases to test
- All values negative → the largest single value ([-3] → −3).
- A negative child that must be dropped: [2,-1] → 2.
- The best path lies wholly inside one subtree, far from the root.
practise next
Similar problems
- #543Diameter of Binary TreeEasyin Tree Recursion
- #53Maximum SubarrayMediumin Arrays & Strings
- #110Balanced Binary TreeEasyin Tree Recursion