LeetCode 662: Maximum Width of Binary Tree Solution in Python – A Step-by-Step Guide
Imagine you’re a tree surveyor tasked with measuring the widest stretch of a binary tree—like [1, 3, 2, 5, 3, null, 9]—counting nodes across each level, including gaps where null nodes lie between the leftmost and rightmost nodes. For example, at level 2, the width might span from 5 to 9, counting nulls in between. That’s the challenge of LeetCode 662: Maximum Width of Binary Tree, a medium-level problem that’s all about calculating the broadest span of a tree. Using Python, we’ll explore two solutions: the Best Solution, a BFS approach with index tracking for efficiency, and an Alternative Solution, a DFS method with level mapping that’s more recursive but complex. With detailed examples, beginner-friendly breakdowns—especially for the BFS method—and clear code, this guide will help you measure that width, whether you’re new to coding or leveling up. Let’s climb that tree and start counting!
What Is LeetCode 662: Maximum Width of Binary Tree?
In LeetCode 662: Maximum Width of Binary Tree, you’re given the root of a binary tree (nodes with val, left, and right attributes), and your task is to find the maximum width across all levels. The width of a level is the number of nodes between the leftmost and rightmost non-null nodes, including any null nodes in between. Return this maximum width as an integer. For example, with root = [1, 3, 2, 5, 3, null, 9], the maximum width is 4 at level 2 (nodes 5 to 9, including nulls). This problem tests your ability to track node positions across tree levels efficiently.
Problem Statement
- Input:
- root: Root node of a binary tree.
- Output: An integer—maximum width of the tree.
- Rules:
- Width = number of nodes (including nulls) between leftmost and rightmost non-null nodes at a level.
- Compute for each level, return maximum.
- Tree may be incomplete or skewed.
Constraints
- Number of nodes: 1 to 3000.
- -100 ≤ Node.val ≤ 100.
Examples
- Input: root = [1, 3, 2, 5, 3, null, 9]
- Output: 4 (Level 2: 5 to 9, width = 4)
- Input: root = [1, 3, null, 5, 3]
- Output: 2 (Level 1: 3 to null, width = 2)
- Input: root = [1, 3, 2, 5]
- Output: 2 (Levels 1 and 2: width = 2)
These examples set the tree—let’s solve it!
Understanding the Problem: Measuring Width
To solve LeetCode 662: Maximum Width of Binary Tree in Python, we need to find the maximum width across all levels of a binary tree, counting nodes (including nulls) between the leftmost and rightmost non-null nodes at each level. A brute-force approach—listing all nodes per level and counting—would work but could be optimized. Since we need positions, we can use BFS or DFS with indexing. We’ll explore:
- Best Solution (BFS with Index Tracking): O(n) time, O(w) space—fast and intuitive (w = max width).
- Alternative Solution (DFS with Level Mapping): O(n) time, O(h) space—recursive but complex (h = height).
Let’s start with the BFS solution, breaking it down for beginners.
Best Solution: BFS with Index Tracking
Why This Is the Best Solution
The BFS with index tracking approach is the top choice for LeetCode 662 because it’s efficient—O(n) time with O(w) space—and uses breadth-first search to process levels sequentially, tracking node indices to compute widths directly. It fits constraints (n ≤ 3000) perfectly and is straightforward once you see the indexing pattern. It’s like measuring each level of the tree as you sweep across it!
How It Works
Think of this as a level measurer:
- Step 1: Initialize Queue:
- Use a queue with (node, index) pairs, root at index 0.
- Step 2: BFS by Level:
- For each level:
- Record leftmost index (first node).
- Process all nodes, enqueue children with indices:
- Left child: 2 * parent_index.
- Right child: 2 * parent_index + 1.
- Width = rightmost index - leftmost index + 1.
- Step 3: Track Maximum Width:
- Update max width per level.
- Step 4: Return Result:
- Return maximum width.
It’s like a width scanner—sweep and measure!
Step-by-Step Example
Example: root = [1, 3, 2, 5, 3, null, 9]
- Step 1: Queue = [(1, 0)], max_width = 0.
- Step 2: BFS:
- Level 0: [(1, 0)], width = 0-0+1 = 1, max_width = 1.
- Enqueue: (3, 0), (2, 1).
- Level 1: [(3, 0), (2, 1)], width = 1-0+1 = 2, max_width = 2.
- Enqueue: (5, 0), (3, 1), (9, 3).
- Level 2: [(5, 0), (3, 1), (9, 3)], width = 3-0+1 = 4, max_width = 4.
- Step 3: No deeper levels, max_width = 4.
- Output: 4.
Code with Detailed Line-by-Line Explanation
Here’s the Python code, explained clearly:
from collections import deque
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def widthOfBinaryTree(self, root: TreeNode) -> int:
# Step 1: Initialize queue and max width
if not root:
return 0
queue = deque([(root, 0)]) # (node, index)
max_width = 0
# Step 2: BFS by level
while queue:
level_size = len(queue)
leftmost = queue[0][1] # First index of level
# Process all nodes in current level
for _ in range(level_size):
node, index = queue.popleft()
# Enqueue children with indices
if node.left:
queue.append((node.left, 2 * index))
if node.right:
queue.append((node.right, 2 * index + 1))
# Compute width of this level
rightmost = queue[-1][1] if queue else index
width = rightmost - leftmost + 1
max_width = max(max_width, width)
# Step 3: Return maximum width
return max_width
- Line 1: Import deque for queue.
- Lines 4-8: TreeNode class (standard).
- Lines 12-16: Init: Queue with root at index 0, max_width.
- Lines 19-33: BFS:
- Process level, track leftmost, enqueue children, compute width.
- Line 36: Return max_width.
- Time Complexity: O(n)—visit each node once.
- Space Complexity: O(w)—queue holds max width.
This is like a tree measurer—scan and count!
Alternative Solution: DFS with Level Mapping
Why an Alternative Approach?
The DFS with level mapping approach uses depth-first search—O(n) time, O(h) space (h = height). It’s more recursive, mapping each node’s index to its level, but requires extra bookkeeping to track widths. It’s like diving into the tree and measuring as you go!
How It Works
Picture this as a depth mapper:
- Step 1: Init level map:
- Dictionary to store leftmost index per level.
- Step 2: DFS:
- Recurse with (node, level, index).
- Update max width using leftmost and current index.
- Step 3: Return max width.
It’s like a depth counter—map and measure!
Step-by-Step Example
Example: Same as above
- Step 1: levels = {}, max_width = 0.
- Step 2: DFS:
- (1, 0, 0): levels[0]=0, width=1, max_width=1.
- (3, 1, 0): levels[1]=0, width=1, max_width=1.
- (5, 2, 0): levels[2]=0, width=1, max_width=1.
- (3, 2, 1): levels[2]=0, width=2-0+1=2, max_width=2.
- (9, 2, 3): levels[2]=0, width=4-0+1=4, max_width=4.
- (2, 1, 1): levels[1]=0, width=2-0+1=2, max_width=4.
- Step 3: Return 4.
- Output: 4.
Code for DFS Approach
class Solution:
def widthOfBinaryTree(self, root: TreeNode) -> int:
# Step 1: Initialize level map and max width
levels = {} # Level -> leftmost index
max_width = [0] # Use list to modify in recursion
# Step 2: DFS with index tracking
def dfs(node, level, index):
if not node:
return
# Record leftmost index for this level
if level not in levels:
levels[level] = index
# Compute width at this level
width = index - levels[level] + 1
max_width[0] = max(max_width[0], width)
# Recurse on children
dfs(node.left, level + 1, 2 * index)
dfs(node.right, level + 1, 2 * index + 1)
dfs(root, 0, 0)
# Step 3: Return maximum width
return max_width[0]
- Lines 4-6: Init: Levels map, max_width as list.
- Lines 9-20: DFS:
- Set leftmost index, compute width, recurse with child indices.
- Line 23: Return max_width.
- Time Complexity: O(n)—visit each node once.
- Space Complexity: O(h)—recursion stack.
It’s a depth measurer—recurse and track!
Comparing the Two Solutions
- BFS (Best):
- Pros: O(n) time, O(w) space, level-wise clarity.
- Cons: Queue space for wide levels.
- DFS (Alternative):
- Pros: O(n) time, O(h) space, recursive elegance.
- Cons: Extra bookkeeping.
BFS wins for simplicity.
Additional Examples and Edge Cases
- Input: [1]
- Output: 1.
- Input: [1, 2, 3, 4, null, null, 5]
- Output: 2.
Both handle these well.
Complexity Breakdown
- BFS: Time O(n), Space O(w).
- DFS: Time O(n), Space O(h).
BFS is optimal for clarity.
Key Takeaways
- BFS: Level scanning—smart!
- DFS: Depth mapping—clear!
- Width: Trees are fun.
- Python Tip: Queues rock—see Python Basics.
Final Thoughts: Measure That Tree
LeetCode 662: Maximum Width of Binary Tree in Python is a fun tree challenge. BFS with index tracking offers speed and intuitiveness, while DFS provides a recursive alternative. Want more? Try LeetCode 102: Binary Tree Level Order Traversal or LeetCode 104: Maximum Depth of Binary Tree. Ready to measure? Head to Solve LeetCode 662 on LeetCode and find that width today!