AlgoMaster Logo

Maximum Width of Binary Tree

mediumFrequency6 min readUpdated June 23, 2026

Understanding the Problem

We need to find the widest level in a binary tree, where "width" has a specific meaning. It is not the count of nodes at a level. It is the distance between the leftmost and rightmost non-null nodes, including any gaps (nulls) in between.

Consider the tree laid out on a grid where the root sits at position 0. Its left child takes position 0 and its right child position 1. At the next level the four possible positions are 0, 1, 2, 3. The width of a level is rightmost_position - leftmost_position + 1.

The challenge is not the traversal. It is assigning each node a positional index so we can measure the span at each level. Numbering nodes the way a binary heap does (root at index 0, left child at 2i, right child at 2i+1) gives every node a position as if the tree were complete, which is what lets us compute the span even when nulls sit between the end nodes.

Key Constraints:

  • Number of nodes in range [1, 3000] -- An O(n) traversal is more than fast enough. The difficulty is correctness with positional indexing, not speed.
  • -100 <= Node.val <= 100 -- Node values do not affect the answer. Only the tree structure matters.
  • At least 1 node -- The tree is never empty, so a null root needs no special handling.
  • Answer fits in 32-bit signed integer -- The final width fits in a 32-bit int. The positional indices do not. In a tree skewed all the way right, the index of the rightmost node at depth d is 2^d - 1, which exceeds even a 64-bit integer once d passes 63. The indexing scheme has to keep these indices small, which drives the design of every approach below.

Approach 1: BFS with Positional Indexing

Intuition

BFS processes a tree level by level, which matches what the problem asks for: the leftmost and rightmost positions are compared within a single level.

Assign each node a heap-style index. A node at index i gives its left child index 2 * i and its right child index 2 * i + 1. The tree does not have to be complete; this numbering assigns a virtual position to every node as if it were. At each level the width is then rightmost_index - leftmost_index + 1.

On a deep, skewed tree these indices grow exponentially and overflow even a 64-bit integer. To bound them, normalize at each level by subtracting the leftmost index before computing children. Only the relative distance between the leftmost and rightmost nodes at a level affects the width, so resetting the leftmost to 0 each level changes nothing about the answer while keeping the largest index at any level below the width of that level.

Algorithm

  1. Create a queue and add the root with index 0.
  2. While the queue is not empty:
    • Record the number of nodes at this level (levelSize).
    • Capture the index of the first node in the queue as leftmost.
    • Process all nodes at this level, recording the index of the last one as rightmost.
    • For each node, enqueue its left child with index 2 * (currentIndex - leftmost) and right child with index 2 * (currentIndex - leftmost) + 1.
    • Update the maximum width as rightmost - leftmost + 1.
  3. Return the maximum width.

Example Walkthrough

root
1Level 0: visit root (1), idx=0. Width = 0-0+1 = 1
1idx:035329
maxWidth
1Level 0 width = 1, update maxWidth
1
1/4

Code

The BFS queue holds up to O(n) nodes at the widest level. DFS replaces that queue with a recursion stack bounded by the tree height, which is smaller on a balanced tree.

Approach 2: DFS with Positional Indexing

Intuition

DFS reaches the same answer without a queue. Each recursive call carries the node's depth and its heap-style index. The first node visited at a given depth records its index as the leftmost for that depth. Every later node at that depth computes its width as currentIndex - leftmostIndex + 1 and updates the running maximum.

The indexing is the same as in BFS: left child at 2 * i, right child at 2 * i + 1, with indices normalized against the leftmost at each level to prevent overflow.

DFS recurses into the left subtree before the right, so the first node reached at any depth is the leftmost one at that depth. A single list storing the first index seen per depth is enough.

Algorithm

  1. Create a list leftmostIndices to store the first index seen at each depth.
  2. Initialize maxWidth = 0.
  3. Define a recursive function dfs(node, depth, index):
    • If node is null, return.
    • If depth equals the size of leftmostIndices, append index (first time visiting this depth).
    • Compute width as index - leftmostIndices[depth] + 1.
    • Update maxWidth if this width is larger.
    • Normalize the index: normalizedIndex = index - leftmostIndices[depth].
    • Recurse on left child with depth + 1 and 2 * normalizedIndex.
    • Recurse on right child with depth + 1 and 2 * normalizedIndex + 1.
  4. Call dfs(root, 0, 0).
  5. Return maxWidth.

Example Walkthrough

root
1DFS visit 1 (depth=0, idx=0). leftmost[0]=0, width=1
1visit35329
maxWidth
1Visit 1: width=1, maxWidth=1
1
1/7

Code