Return the node values grouped by level, top to bottom.
Recognizing that 'level by level' means a queue, not recursion.
Use a queue. The trick: snapshot the queue's length at the start of each level — that count is exactly the nodes on the current level. Process that many, enqueuing their children for the next round. This 'level size' technique is what separates rings cleanly without storing a depth on every node. Note that `queue.shift()` on a JS array is O(n); for large inputs mention a real queue (two-pointer head index, or a deque) to keep it O(n) overall. The same level-snapshot pattern gives you zigzag traversal, right-side-view, and level averages.
'Level by level', 'nearest', or 'minimum number of steps' → BFS with a queue.
Time O(n) · Space O(n)