Given the root of a binary tree, return the level-order traversal of its nodes' values — the values grouped level by level, from left to right, top to bottom.
The tree is given in level-order (breadth-first), using null for missing children.
Input: root = [3, 9, 20, null, null, 15, 7] Output: [[3], [9, 20], [15, 7]] Level 0 is [3], level 1 is [9, 20], level 2 is [15, 7].
Input: root = [1] Output: [[1]] A single node forms one level.
Input: root = [] Output: [] An empty tree has no levels.
- The number of nodes is in the range [0, 2000] - -1000 <= Node.val <= 1000
Level-order (breadth-first) visits the tree one level at a time, left to right. The natural tool is a queue: process the nodes currently in it as one level, collecting their values while enqueuing their children for the next level.
“Grouped by level or one flat list?”
Grouped: return a list per level, each left-to-right.
“What about an empty tree?”
Return an empty list.
Level-order is breadth-first, so I use a queue and process it one level at a time.
At each step I snapshot how many nodes are in the queue — that's the current level — pop exactly that many, collect their values, and enqueue their children.
Worked example — tree [3, 9, 20, null, null, 15, 7]
3
/ \
9 20
/ \
15 7
level 0: [3]
level 1: [9, 20]
level 2: [15, 7]
result: [[3], [9, 20], [15, 7]]
Recording len(queue) before the inner loop separates one level from the next without any per-node depth bookkeeping.
Enqueue left before right, and each level naturally comes out in left-to-right order.
Each node is enqueued/dequeued once (O(n)); the queue holds at most one level, up to O(n) for the widest level.
| BFS with a queue | DFS with a depth index | |
|---|---|---|
| Idea | Process the queue one level at a time | Recurse, appending each value to res[depth] |
| Time | O(n) | O(n) |
| Space | O(n) queue | O(height) recursion |
Both are O(n); BFS is the canonical level-order, DFS-by-depth is a neat alternative. Full code is in the Approaches selector below.
Key takeaway
Level-order = breadth-first with a queue. Snapshot the queue size to bound each level, pop that many nodes into a row, and enqueue their children. O(n) time and space.
levelOrder(root):
q = [root]; res = []
while q not empty:
row = []
for _ in range(len(q)):
node = q.pop_front()
row.append(node.val)
enqueue node's children
res.append(row)