Maximum Width of Binary Tree in DSA Typescript - Time & Space Complexity
We want to understand how the time needed to find the maximum width of a binary tree changes as the tree grows.
How does the number of nodes affect the work done?
Analyze the time complexity of the following code snippet.
function widthOfBinaryTree(root: TreeNode | null): number {
if (!root) return 0;
let maxWidth = 0;
const queue: Array<[TreeNode, number]> = [[root, 0]];
while (queue.length > 0) {
const levelLength = queue.length;
const levelHeadIndex = queue[0][1];
for (let i = 0; i < levelLength; i++) {
const [node, index] = queue.shift()!;
if (node.left) queue.push([node.left, 2 * (index - levelHeadIndex)]);
if (node.right) queue.push([node.right, 2 * (index - levelHeadIndex) + 1]);
}
const levelTailIndex = queue.length > 0 ? queue[queue.length - 1][1] : 0;
maxWidth = Math.max(maxWidth, levelTailIndex + 1);
}
return maxWidth;
}
This code finds the maximum width of a binary tree by traversing each level and tracking node positions.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop processes each level of the tree, and the inner for loop visits every node at that level.
- How many times: Each node is visited exactly once during the traversal.
As the number of nodes (n) increases, the code visits each node once, so the work grows directly with n.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 visits |
| 100 | About 100 visits |
| 1000 | About 1000 visits |
Pattern observation: The number of operations grows linearly as the tree size grows.
Time Complexity: O(n)
This means the time to find the maximum width grows in direct proportion to the number of nodes in the tree.
[X] Wrong: "The time depends on the height of the tree only because we process level by level."
[OK] Correct: Even though we go level by level, every node is still visited once, so the total work depends on the total number of nodes, not just the height.
Understanding how tree traversal time grows helps you explain your approach clearly and shows you know how to analyze algorithms well.
"What if we used a depth-first search instead of breadth-first search? How would the time complexity change?"
Practice
Solution
Step 1: Understand the definition of width in a binary tree
The width is the count of nodes at a particular level in the tree.Step 2: Identify maximum width
The maximum width is the largest such count among all levels.Final Answer:
The largest number of nodes present at any single level of the tree -> Option AQuick Check:
Maximum width = max nodes at any level [OK]
- Confusing width with height of the tree
- Thinking width is total nodes in the tree
- Assuming width is sum of node values
Solution
Step 1: Identify traversal method for levels
Level order traversal visits nodes level by level, which uses a queue.Step 2: Choose data structure for level order
A queue allows FIFO order, perfect for processing nodes in each level sequentially.Final Answer:
Queue -> Option AQuick Check:
Level order traversal uses queue [OK]
- Using stack which is LIFO, not suitable for level order
- Using set which doesn't maintain order
- Using map which is key-value, not for traversal order
class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val: number) {
this.val = val;
this.left = null;
this.right = null;
}
}
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.right.right = new TreeNode(5);
function maxWidth(root: TreeNode | null): number {
if (!root) return 0;
const queue: Array<TreeNode> = [root];
let maxWidth = 0;
while (queue.length > 0) {
const levelSize = queue.length;
maxWidth = Math.max(maxWidth, levelSize);
for (let i = 0; i < levelSize; i++) {
const node = queue.shift()!;
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
}
return maxWidth;
}
console.log(maxWidth(root));Solution
Step 1: Analyze tree structure and levels
Level 1: Node 1 (width 1) Level 2: Nodes 2, 3 (width 2) Level 3: Nodes 4, 5 (width 2)Step 2: Check code logic for max width
Code tracks queue length per level and updates maxWidth. Max width found is 2 at levels 2 and 3.Final Answer:
2 -> Option BQuick Check:
Max width = 2 nodes at widest level [OK]
- Counting total nodes instead of per level
- Assuming width is height of tree
- Ignoring null children in width calculation
function maxWidth(root: TreeNode | null): number {
if (!root) return 0;
const queue: Array<TreeNode> = [root];
let maxWidth = 0;
while (queue.length > 0) {
const levelSize = queue.length;
maxWidth = Math.max(maxWidth, levelSize);
for (let i = 0; i <= levelSize; i++) {
const node = queue.shift()!;
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
}
return maxWidth;
}Solution
Step 1: Examine the for loop condition
The loop runs from i = 0 to i <= levelSize, which means it runs levelSize + 1 times.Step 2: Identify impact of off-by-one error
Calling queue.shift() one extra time causes undefined or error because queue is empty after levelSize removals.Final Answer:
The for loop condition should be i < levelSize, not i <= levelSize -> Option CQuick Check:
Loop runs exactly levelSize times [OK]
- Using <= instead of < in loops causing extra iteration
- Confusing queue with stack for level order
- Updating maxWidth inside loop incorrectly
Solution
Step 1: Understand the problem with missing nodes
Simply counting nodes misses gaps caused by nulls, so width must consider positions.Step 2: Use indexing like a complete binary tree
Assign indices to nodes: root = 0, left child = 2*index, right child = 2*index + 1. Track min and max indices per level to find width including gaps.Final Answer:
Assign an index to each node as if the tree was a complete binary tree, then calculate width as rightmost index - leftmost index + 1 per level -> Option DQuick Check:
Index nodes to include null gaps [OK]
- Ignoring null gaps and counting only nodes
- Using stack which breaks level order
- Summing node values instead of counting width
Ready to prove it?
Pass the test and this pattern moves unknown
