The tell: Output grouped by depth, which recursion does not give you for free.
How you get there
1BFS with a queue visits nodes in depth order.
2Record the queue length at the start of each round — that is exactly one level.
3Process precisely that many nodes before starting the next level.
Solution
Python
from collections import deque
def level_order(root) -> list[list[int]]:
if not root:
return []
out: list[list[int]] = []
queue = deque([root])
while queue:
level = []
for _ in range(len(queue)): # snapshot the level size
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
out.append(level)
return out
Time
O(n)
Space
O(n)
What goes wrong
Iterating the queue without snapshotting its length mixes the next level into the current one.