Binary Tree Level Order Traversal
Freeze the queue size, pop one level, enqueue the next
A queue naturally processes nodes in the order they were discovered, which is exactly breadth-first order — but by itself it does not know where one level ends and the next begins. The trick is to read the queue's length before popping anything: that count is exactly how many nodes belong to the current level, since every child enqueued during this round is pushed to the back, after all of this level's nodes. Pop exactly that many, collect their values into one row, and whatever is left in the queue is entirely the next level.
Details
Animated on: root = [3,9,20,null,null,15,7] — return the node values grouped by depth level, top to bottom, left to right. Expected: [[3],[9,20],[15,7]].
Problem:Binary Tree Level Order TraversalMedium
Pattern:Tree BFS and Level Order
Freeze the queue size, pop one level, enqueue the next
step 1 / 15
Call stack
Seed the queue with the root, 3. A queue gives FIFO order, so whatever goes in first (this level) comes out first — that is what keeps the levels from mixing.
1FUNCTION levelOrder(root):2 IF root = null:3 RETURN []4 queue <- [root]5 WHILE queue is not empty:6 k <- LENGTH(queue)7 row <- []8 FOR i <- 1 TO k:9 node <- DEQUEUE(queue)10 APPEND node.val TO row11 IF node.left != null: ENQUEUE(queue, node.left)12 IF node.right != null: ENQUEUE(queue, node.right)13 APPEND row TO result14 RETURN result
← / → step · space play · Home restart
Every step in words
Show all 15 steps
- Seed the queue with the root, 3. A queue gives FIFO order, so whatever goes in first (this level) comes out first — that is what keeps the levels from mixing.
- Freeze the queue's current size, k=1, before popping anything. Everything popped in the next 1 step belongs to level 0; any child enqueued during that span already belongs to level 1, and freezing k up front is what keeps the two from mixing.
- Dequeue 3 and append it to level 0's row: [3]. 1 of 1 popped for this level so far.
- 3's non-null children (9, 20) go on the back of the queue — level 1 material, never touched this round since k=1 was already fixed.
- Level 0 is complete: [3]. Result so far: [[3]].
- Freeze the queue's current size, k=2, before popping anything. Everything popped in the next 2 steps belongs to level 1; any child enqueued during that span already belongs to level 2, and freezing k up front is what keeps the two from mixing.
- Dequeue 9 and append it to level 1's row: [9]. 1 of 2 popped for this level so far.
- Dequeue 20 and append it to level 1's row: [9, 20]. 2 of 2 popped for this level so far.
- 20's non-null children (15, 7) go on the back of the queue — level 2 material, never touched this round since k=2 was already fixed.
- Level 1 is complete: [9, 20]. Result so far: [[3],[9,20]].
- Freeze the queue's current size, k=2, before popping anything. Everything popped in the next 2 steps belongs to level 2; any child enqueued during that span already belongs to level 3, and freezing k up front is what keeps the two from mixing.
- Dequeue 15 and append it to level 2's row: [15]. 1 of 2 popped for this level so far.
- Dequeue 7 and append it to level 2's row: [15, 7]. 2 of 2 popped for this level so far.
- Level 2 is complete: [15, 7]. Result so far: [[3],[9,20],[15,7]].
- Done: [[3],[9,20],[15,7]]. Every node is enqueued once and dequeued once, so the whole traversal costs O(n) time; the queue holds at most one level's worth of nodes, O(n) space in the worst case (a full last level).
Now solve it yourself
Watching is the first half. The second is writing it without the animation.