Maximum Level Sum of a Binary Tree — LeetCode 1161 BFS Pattern
Advertisement
Problem Statement
Given the root of a binary tree where the level of the root is 1, return the smallest level x such that the sum of all node values on level x is maximal.
Constraints:
- The number of nodes in the tree is in the range
[1, 10^4] -10^5 <= Node.val <= 10^5
Input: root = [1,7,0,7,-8,null,null]
Output: 2Input: root = [989,null,10250,98693,-89388,null,null,null,-32127]
Output: 2Why This Problem Matters
LeetCode 1161 — Maximum Level Sum of a Binary Tree — is a high-frequency BFS question at Amazon, Meta, Uber, and Microsoft. It looks like a basic level-order traversal, but the twist of returning the smallest level (i.e., the first one) on a tie tests careful comparison logic — a common spot where candidates lose points.
Interviewers love this problem because it can be solved in three lines with the right pattern but requires negative-value awareness, since Node.val can be -10^5. Initialize the running max to -infinity, not 0, or you'll silently fail on all-negative trees.
This pattern appears in real-world analytics: identifying the "hottest" tier of a hierarchy, finding the layer with maximum aggregated metric in a routing tree, or selecting the most-loaded shard layer in a sharded database.
The Core Insight
Run BFS, keep a level counter starting at 1. For each level, sum the node values, compare against the running maximum, and update the answer level only when we strictly exceed the current max — strict comparison ensures we keep the smallest level on ties.
DFS also works: pass depth recursively and accumulate level_sums[depth] += node.val in a hashmap or list, then scan for the index of the max.
Visual Dry Run
Tree [1, 7, 0, 7, -8]:
| Level | Nodes | Sum | Best so far | Best level |
|---|---|---|---|---|
| 1 | [1] | 1 | 1 | 1 |
| 2 | [7, 0] | 7 | 7 | 2 |
| 3 | [7, -8] | -1 | 7 (no update) | 2 |
Answer: level 2.
Solution (Optimal)
from collections import deque
from typing import Optional
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def maxLevelSum(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
queue = deque([root])
best_level = 1
best_sum = float('-inf')
level = 0
while queue:
level += 1
level_sum = 0
for _ in range(len(queue)):
node = queue.popleft()
level_sum += node.val
if node.left is not None:
queue.append(node.left)
if node.right is not None:
queue.append(node.right)
if level_sum > best_sum:
best_sum = level_sum
best_level = level
return best_levelvar maxLevelSum = function(root) {
if (!root) return 0;
const queue = [root];
let bestLevel = 1;
let bestSum = -Infinity;
let level = 0;
while (queue.length > 0) {
level += 1;
let levelSum = 0;
const size = queue.length;
for (let i = 0; i < size; i++) {
const node = queue.shift();
levelSum += node.val;
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
if (levelSum > bestSum) {
bestSum = levelSum;
bestLevel = level;
}
}
return bestLevel;
};Time: O(n) — each node enqueued and dequeued once. Space: O(w) — queue holds at most the widest level.
Common Mistakes
- Initializing
bestSum = 0. With negative values like-10^5, you'll incorrectly return level 1. - Using
>=instead of>and updating to a later level on ties. - Computing depth via DFS but forgetting to track
level_sumsper index, leading to off-by-one between 0-indexed depth and 1-indexed level. - Forgetting that the root is level 1, not level 0.
- Using
queue.shift()repeatedly in JavaScript onn = 10^4is fine but slow; for larger inputs prefer an index pointer.
Interview Tips
- Mention both BFS and DFS solutions. BFS is cleaner here.
- Walk through the tie-breaker: "I update only when strictly greater, so the smallest level wins."
- Ask: "Are levels 1-indexed?" if not stated. Most LeetCode tree-level problems use 1-indexed levels.
- Sketch a small tree with negative leaves to highlight the
-infinityinitialization.
Follow-up Questions
- "Smallest level with minimum sum" — Flip the comparator to
<with+infinityinitial. - "Average per level instead of sum" — LC 637, divide by level size.
- "K-ary tree variant" — Replace
node.left, node.rightwith a children loop. - "Streaming variant: nodes arrive online" — Maintain per-level sums in a hashmap keyed by depth.
- "Level with max odd-valued sum" — Filter inside the inner loop before adding.
Key Takeaways
- LeetCode 1161 Maximum Level Sum returns the smallest 1-indexed level with maximal node sum.
- BFS with a level counter and strict-greater comparison gives O(n) time, O(w) space.
- Initialize the running max to negative infinity to handle trees of negative values.
- DFS with a depth-indexed sum array works equivalently in O(n).
- Strict-greater (
>) preserves the smallest-level tie-breaker;>=would be a bug. - Frequent at Amazon, Meta, and Uber as a BFS pattern check.
- Generalizes to "find the layer with extreme aggregate" across many tree analytics tasks.
Advertisement