Binary Tree Maximum Path Sum
Binary Tree Maximum Path Sum
Section titled “Binary Tree Maximum Path Sum”
Hard
Day 13 • Striver Blind 75
📌 Problem Overview
Section titled “📌 Problem Overview”A path in a binary tree is a sequence of nodes connected by edges, with no node repeated. Given the root of a binary tree, return the maximum path sum of any non-empty path (it need not pass through the root).
Examples & Constraints
Section titled “Examples & Constraints”Example 1:
- Input:
root = [1,2,3] - Output:
6
Example 2:
- Input:
root = [-10,9,20,null,null,15,7] - Output:
42
Constraints:
The number of nodes is in the range [1, 3 × 10⁴]-1000 ≤ Node.val ≤ 1000
💡 Approach & Intuition
Section titled “💡 Approach & Intuition”Binary Tree Maximum Path Sum is the hardest classic tree DFS problem: distinguishing between a path returned to the parent (must be one-directional) and the best path bending through a node (can use both children).
🎯 Pattern Recognition
Section titled “🎯 Pattern Recognition”Pattern: Post-Order DFS with Two Return Concepts
Each call returns the best downward extension for its parent (clamped to 0 if negative), while a global max separately considers the node acting as a bend point using both children.
📊 Step-by-Step Execution (Mermaid Diagram)
Section titled “📊 Step-by-Step Execution (Mermaid Diagram)”graph TD Root["TreeNode (Root)"] -->|Recurse Left| Left["Left Subtree"] Root -->|Recurse Right| Right["Right Subtree"] Left --> Base1{"Base Case (null)"} Right --> Base2{"Base Case (null)"} Base1 --> Combine["Combine Results"] Base2 --> Combine Combine --> Ans["Return Root Value / Depth"]🐢 Brute Force Solution
Section titled “🐢 Brute Force Solution”// Enumerating every possible path explicitly is exponential and impractical// The DFS-with-two-concepts approach below is the standard efficient solutionfunction maxPathSum(values) { const root = buildTree(values); let best = -Infinity; function dfs(node) { if (!node) return 0; const l = Math.max(dfs(node.left), 0); const r = Math.max(dfs(node.right), 0); best = Math.max(best, node.val + l + r); return node.val + Math.max(l, r); } dfs(root); return best;}- Time Complexity:
O(n) - Space Complexity:
O(h) - Explanation: There’s no simpler correct approach than the linear DFS below.
⚡ Optimized Solution
Section titled “⚡ Optimized Solution”class TreeNode { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; }}function buildTree(values) { if (!values.length || values[0] === null) return null; const root = new TreeNode(values[0]); const queue = [root]; let i = 1; while (queue.length && i < values.length) { const node = queue.shift(); if (i < values.length) { const lv = values[i++]; if (lv !== null) { node.left = new TreeNode(lv); queue.push(node.left); } } if (i < values.length) { const rv = values[i++]; if (rv !== null) { node.right = new TreeNode(rv); queue.push(node.right); } } } return root;}function maxPathSum(values) { const root = buildTree(values); let best = -Infinity; function dfs(node) { if (!node) return 0; const l = Math.max(dfs(node.left), 0); const r = Math.max(dfs(node.right), 0); best = Math.max(best, node.val + l + r); return node.val + Math.max(l, r); } dfs(root); return best;}- Time Complexity:
O(n) - Space Complexity:
O(h) - Explanation: Single post-order DFS tracking both a return value and a global best.
🐾 Step-by-Step Walkthrough
Section titled “🐾 Step-by-Step Walkthrough”- Initialize State: Setup necessary pointers, dynamic programming arrays, or hash maps.
- Iterate & Evaluate: Process the input according to the boundary conditions.
- Update & Return: Compute the optimal answer and return early or at termination.
🎙️ FAANG Interview Pitch
Section titled “🎙️ FAANG Interview Pitch”- The key insight: what a node returns to its parent differs from the best path through it
- A node can only pass ONE direction upward (can’t fork after returning)
- But the global best CAN fork at any node, using both children
- Clamp negative subtree contributions to 0 — never worth including a net-negative branch
💡 Progressive Hints
Section titled “💡 Progressive Hints”- A negative subtree contribution should be clamped to 0 (skip it).
- Track a global max considering node.val + leftGain + rightGain (a bend through this node).
- Return to the parent only node.val + max(leftGain, rightGain), since a path passed up can extend in only one direction.