Maximum Width of Binary Tree
You are given the root of a binary tree. Picture every level of the tree laid out as if the tree were complete, so that each level d has 2d slots, and missing nodes still occupy their slots.
The width of a level is the number of slots from its leftmost real node to its rightmost real node, inclusive; empty slots between those two ends count, empty slots outside them do not. Return the largest width over all levels.
The tree is given as a level-order array where null marks a missing child.
Example 1
Example 2
Example 3
Constraints
1 <= number of nodes <= 3000-100 <= Node.val <= 100- The answer fits in a signed 32-bit integer.
Pattern Path · Trees: BFS · problem 94 of 169
i, its children are in slots 2i and 2i + 1.last index - first index + 1.Start simple
Materialise every level as a full array of 2d slots (with placeholders for missing nodes) and scan it: exponential time and memory on deep, sparse trees.
The key idea
Give every node a position: the root is 0, and a node at position i has children at 2i and 2i + 1. These are exactly the slot numbers the node would have in a complete tree, so the width of a level is simply the difference between the positions of its last and first nodes, plus one. Empty slots never need to be stored.
A breadth-first search visits each level left to right, so the first and last entries in the queue for a level are its two ends.
The catch is size: positions double on every level, so a chain 1000 nodes deep reaches about 21000. Only differences within a level matter, so before expanding a level subtract the position of its first node from every node on it. Shifting a whole level by the same amount shifts all of its children by the same amount too, leaving every later difference unchanged, while keeping the numbers no larger than twice the widest width seen.
Complexity
- Time:
O(n) - Space:
O(w)
Python
from collections import deque
class Solution:
def widthOfBinaryTree(self, root):
best = 0
level = deque([(root, 0)]) # (node, slot position within its level)
while level:
first = level[0][1]
last = level[-1][1]
best = max(best, last - first + 1)
for _ in range(len(level)):
node, pos = level.popleft()
pos -= first # normalise so positions stay small
if node.left:
level.append((node.left, 2 * pos))
if node.right:
level.append((node.right, 2 * pos + 1))
return best
JavaScript
var widthOfBinaryTree = function(root) {
let best = 0;
let level = [[root, 0]]; // [node, slot position within its level]
while (level.length > 0) {
const first = level[0][1];
const last = level[level.length - 1][1];
best = Math.max(best, last - first + 1);
const next = [];
for (const [node, p] of level) {
const pos = p - first; // normalise so positions stay small
if (node.left) next.push([node.left, 2 * pos]);
if (node.right) next.push([node.right, 2 * pos + 1]);
}
level = next;
}
return best;
};
What the interviewer is checking
The interviewer wants to see you turn a geometric description into heap-style indexing, and then notice (or be nudged towards) the overflow problem and fix it with per-level normalisation.
Mistakes to avoid
- Counting only the real nodes on a level instead of the slots between its two ends.
- Letting positions grow unchecked: on a deep chain they overflow fixed-width integers (or become
Infinityin JavaScript) unless you renormalise each level. - Counting empty slots to the left of the first node or to the right of the last one.
Follow-ups to expect
- Can you do it with DFS instead of BFS? (Record first position per depth.)
- Return which level is widest, not just its width. (Track the depth alongside the best.)
- What if the width could exceed 64 bits? (Normalise positions, or use big integers.)
In real software
Tree-drawing tools compute the horizontal extent of each level in the same way to decide how much canvas a layout needs, and heap-style indexing is how binary heaps and segment trees are stored in flat arrays.