Binary Tree Zigzag Level Order Traversal
Same BFS queue, a row index that flips direction each level
The queue still discovers nodes in the same left-to-right order every time — that discovery order must never change, or parent-child relationships get scrambled. What flips is only where each dequeued value is WRITTEN: a pre-sized row plus a direction-dependent index (i, or k-1-i) places values into zigzag order directly, with no separate reversal step needed.
Details
Animated on: root = [3,9,20,null,null,15,7] — return node values grouped by level, alternating left-to-right and right-to-left each level. Expected: [[3],[20,9],[15,7]].
Problem:Binary Tree Zigzag Level Order TraversalMedium
Pattern:Tree BFS and Level Order
Same BFS queue, a row index that flips direction each level
step 1 / 14
Call stack
Level 0 begins with 1 node in the queue. leftToRight is true, so this level's values land front-to-back in a row of size 1.
1FUNCTION zigzagLevelOrder(root):2 queue <- [root], leftToRight <- true, result <- []3 WHILE queue is not empty:4 k <- LENGTH(queue), row <- new array of size k5 FOR i <- 0 TO k - 1:6 node <- DEQUEUE(queue)7 idx <- IF leftToRight THEN i ELSE k - 1 - i8 row[idx] <- node.val9 IF node.left != null: ENQUEUE(queue, node.left)10 IF node.right != null: ENQUEUE(queue, node.right)11 APPEND row TO result12 leftToRight <- NOT leftToRight13 RETURN result14END FUNCTION
← / → step · space play · Home restart
Every step in words
Show all 14 steps
- Level 0 begins with 1 node in the queue. leftToRight is true, so this level's values land front-to-back in a row of size 1.
- Dequeue 3 (1 of 1 popped this level). idx = i = 0, so row[0] <- 3 -> [3].
- 3's children (9, 20) join the back of the queue for level 1 — enqueue order never flips, only the row-placement index does.
- Level 0 finished: [3]. result = [[3]]. Toggle direction -> right-to-left for level 1.
- Level 1 begins with 2 nodes in the queue. leftToRight is false, so this level's values land back-to-front in a row of size 2.
- Dequeue 9 (1 of 2 popped this level). idx = k-1-i = 1, so row[1] <- 9 -> [_, 9]. 9 is a leaf, so nothing new is enqueued.
- Dequeue 20 (2 of 2 popped this level). idx = k-1-i = 0, so row[0] <- 20 -> [20, 9].
- 20's children (15, 7) join the back of the queue for level 2 — enqueue order never flips, only the row-placement index does.
- Level 1 finished: [20, 9]. result = [[3], [20, 9]]. Toggle direction -> left-to-right for level 2.
- Level 2 begins with 2 nodes in the queue. leftToRight is true, so this level's values land front-to-back in a row of size 2.
- Dequeue 15 (1 of 2 popped this level). idx = i = 0, so row[0] <- 15 -> [15, _]. 15 is a leaf, so nothing new is enqueued.
- Dequeue 7 (2 of 2 popped this level). idx = i = 1, so row[1] <- 7 -> [15, 7]. 7 is a leaf, so nothing new is enqueued.
- Level 2 finished: [15, 7]. result = [[3], [20, 9], [15, 7]]. Queue is empty, so the traversal ends here.
- Zigzag level order traversal complete: [[3],[20,9],[15,7]]. Each node is dequeued and placed exactly once, so this costs O(n) time; the queue and result together hold O(n) space.
Now solve it yourself
Watching is the first half. The second is writing it without the animation.