Pattern #40
Tree BFS / Level Order Traversal
Important interview questions, thinking patterns, levelSize snapshot rule, BFS vs DFS comparison, Minimum Depth early stop, and Go code templates.
Must Solve
15 core questions — solve these first.
- 1.Binary Tree Level Order TraversalSnapshot levelSize = len(queue) before inner loop: process level nodes into level slicemedium
- 2.Binary Tree Zigzag Level Order TraversalLevel order + boolean flag leftToRight: reverse level slice on alternate levelsmedium
- 3.Binary Tree Right Side ViewLevel order: append last node of each level slice (i == levelSize - 1)medium
- 4.Average of Levels in Binary TreeLevel order: sum level values and append sum / float64(levelSize)easy
- 5.Minimum Depth of Binary TreeBFS early stop: return level depth as soon as first leaf (Left == nil && Right == nil) is popped!easy
- 6.Maximum Width of Binary TreePositional 1-based indexing (2*i, 2*i+1): width = rightPos - leftPos + 1 at each levelmedium
- 7.Find Largest Value in Each Tree RowLevel order: track max value across each level slicemedium
- 8.Populating Next Right Pointers in Each NodeLevel order: set node.Next = nextNodeInLevel (prevNode.Next = currNode)medium
- 9.Populating Next Right Pointers IILevel order handling non-perfect binary trees, or pointer traversalmedium
- 10.Cousins in Binary TreeLevel order: track parent pointers & depth, confirm same depth but different parentseasy
- 11.Even Odd TreeLevel order checking strict index parity & strictly increasing/decreasing values per levelmedium
- 12.Check Completeness of a Binary TreeBFS queue including nil nodes: once a nil is popped, no non-nil node can ever appear!medium
- 13.Add One Row to TreeBFS stop at target depth - 1: insert new nodes between parent & left/right childrenmedium
- 14.Deepest Leaves SumLevel order sum: sum of nodes at final level slicemedium
- 15.Find Bottom Left Tree ValueLevel order: store first node of each level (i == 0)medium
Also Important
8 more questions worth practicing.
- 16.N-ary Tree Level Order TraversalLevel order pushing all children slice (for _, child := range node.Children)medium
- 17.Reverse Level Order TraversalLevel order storing level slices, then reverse the result array at the endmedium
- 18.Vertical Order TraversalBFS tracking (col, row) coordinates + sort by col then row then valuemedium
- 19.Bottom View of Binary TreeBFS column map overwriting values col by col from top to bottommedium
- 20.Top View of Binary TreeBFS column map storing only first node seen per columnmedium
- 21.Nodes at Distance KBFS from target node after building graph / parent pointersmedium
- 22.Maximum Level Sum of a Binary TreeLevel order: track level sum & return 1-based level index with maximum summedium
- 23.Minimum Number of Operations to Sort a Binary Tree by LevelLevel order + min cycle swaps algorithm to sort each level slicemedium
How to Think
- Need level by level traversal?Tree BFS + Queue (FIFO)
- Need nearest / minimum depth?BFS (reaches shallow nodes first)
- Need rightmost node of every level?Level Order + last element (i == levelSize - 1)
- Need largest / average / sum per level?BFS + levelSize aggregation loop
- Need zigzag order?BFS + alternate level direction flag
Go Tree BFS Level Order Template
Standard Level-by-Level Queue Loop in Go
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
// Tree BFS Level Order Traversal in Go
func levelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
result := [][]int{}
queue := []*TreeNode{root}
head := 0 // Efficient head pointer instead of re-slicing array!
for head < len(queue) {
levelSize := len(queue) - head // CRUCIAL: Snapshot queue size before processing level!
currentLevel := make([]int, 0, levelSize)
for i := 0; i < levelSize; i++ {
node := queue[head]
head++
currentLevel = append(currentLevel, node.Val)
if node.Left != nil {
queue = append(queue, node.Left)
}
if node.Right != nil {
queue = append(queue, node.Right)
}
}
result = append(result, currentLevel)
}
return result
}👉 Total Time: O(N) | Space: O(W) where W = max tree width
The Golden Rule: Snapshot levelSize BEFORE the Loop
Before processing any level, snapshot levelSize = len(queue) - head! Process exactly that many nodes in the inner loop so that newly appended children are safely preserved for the NEXT level.
// Minimum Depth of Binary Tree using BFS (Early Stop!)
func minDepth(root *TreeNode) int {
if root == nil {
return 0
}
queue := []*TreeNode{root}
depth := 1
for len(queue) > 0 {
levelSize := len(queue)
for i := 0; i < levelSize; i++ {
node := queue[0]
queue = queue[1:]
// First leaf encountered in BFS is automatically at minimum depth!
if node.Left == nil && node.Right == nil {
return depth
}
if node.Left != nil {
queue = append(queue, node.Left)
}
if node.Right != nil {
queue = append(queue, node.Right)
}
}
depth++
}
return depth
}👉 Time: O(N) worst case, but stops as soon as first shallow leaf is popped!
BFS vs DFS Comparison
Processes nodes level-by-level horizontally. Ideal for Level Order, Minimum Depth, Right Side View, Per-level Aggregations, Nearest Nodes. Memory = O(Width).
Explores subtrees deep down vertically. Ideal for Height, Max Path Sum, Subtree DP, LCA, Root-to-Leaf Paths. Memory = O(Height).
LEVEL / NEAREST → Use Tree BFS (Queue FIFO)
PATH / SUBTREE → Use Tree DFS (Recursion)
levelSize → Snapshot len(queue) BEFORE inner loop
Min Depth → BFS early stop on first leaf node
Right Side View → Take last element of each level slice💡 Golden Rule: "Snapshot the current queue size, process exactly that many nodes, and everything you add belongs to the next level."
Common Interview Mistakes
If you don't store levelSize = len(queue) before the inner loop, children get mixed with parents in the same level slice!
Doing queue = queue[1:] repeatedly re-allocates slice headers. Use a logical head pointer index for cleaner memory usage.
When the problem explicitly asks for level-by-level output or nearest nodes, use BFS rather than simulating level maps via DFS.
A node with only one child is NOT a leaf! A true leaf node requires node.Left == nil && node.Right == nil.
Interview Rules
- 1. Level by level traversal? → Tree BFS
- 2. Queue structure? → FIFO (First In First Out)
- 3. Level slice separation? → Snapshot
levelSize = len(queue)before inner loop - 4. Minimum depth / nearest level? → BFS early stop on first leaf node
- 5. Right side view? → Append last node of each level slice (
i == levelSize - 1) - 6. Bottom left value? → First node of deepest level slice (
i == 0) - 7. Zigzag order? → BFS + direction flag toggle (
leftToRight = !leftToRight) - 8. Overall Complexity → Time:
O(N)| Queue Space:O(W)where W is maximum tree width (O(N)worst case)
Small Rules
- Rule 1: Tree BFS always relies on a Queue FIFO structure.
- Rule 2: Always capture levelSize before adding children in the loop.
- Rule 3: BFS is strong for minimum depth because shallow levels are processed first.
- Rule 4: Per-level calculations (sum, average, max) aggregate inside the inner level loop.
- Rule 5: BFS space depends on maximum tree width, not height.
Production Thinking
Organization Level Processing → Processing employees by hierarchy level (CEO -> Managers -> Engineers)
UI / DOM Depth Inspection → Inspecting DOM component trees layer by layer for layout metrics
Shallow Nearby File Search → Finding nearest matching configuration files before deep recursive searches
Multi-hop Network Distance → Evaluating 1-hop, 2-hop, 3-hop network service dependencies
Remember This
Tree BFS → Queue FIFO
Level Order → levelSize
Process → Current level only
Children → Next level
Minimum depth → First leaf found
Right side view → Last node
Bottom left → First node
Zigzag → Alternate direction
Time → O(N)
Space → O(Width)💡 Golden Rule: "Snapshot the current queue size, process exactly that many nodes, and everything you add belongs to the next level."