Skip to content
mlmentorship

Binary Tree Level Order Traversal

Return tree values one level at a time.

Published · 4 min read ·Core ·Intermediate

30-second answer map

Visual first · depth when needed

Snapshotting the queue length separates the current tree level from children appended for the next level.

Preparing the visual…

ML breadth · active recall

Practice before you read

8 minutes. Explain the mechanism, why it works, when it fails, and one alternative.

How practice works

ML breadth · closed-book attempt

Binary Tree Level Order Traversal

Explain the mechanism, why it works, when it fails, and one alternative.

08:00recommended time

Closing or reloading clears the scratchpad. Only score, weak rubric dimensions, attempt count, and retry date can be stored locally.

Return tree values one level at a time.

Start with the concrete trace below. It shows the state the algorithm must carry as it runs.

Problem trace

Binary Tree Level Order Traversal: Snapshotting the queue length separates the current tree level from children appended for the next level.

Input and goalReturn tree values one level at a time.
Queue the rootFor tree [3,9,20,null,null,15,7], initialize answer = [] and queue = [3]. The drawn edges show 3 -> 9, 3 -> 20, 20 -> 15, and 20 -> 7.
queueState[3]answer[]

Recognize it
Use this BFS form when a tree answer is grouped by depth, processed left-to-right by level, or must compute one aggregate per level rather than one flat visitation order.
Keep true
At each while-loop start, the queue contains exactly one complete next level in left-to-right order. Iterating the captured length consumes only that level while appending its children for the following level.
Reuse it
Capture the frontier size before expanding it whenever output or timing is grouped by BFS depth; this transfers to right-side view, level averages, shortest unweighted paths, and wave simulations.
Read it this way: For tree [3,9,20,null,null,15,7], initialize answer = [] and queue = [3]. The drawn edges show 3 -> 9, 3 -> 20, 20 -> 15, and 20 -> 7. Step through the frames to watch the state change. The last frame shows the answer or the stopping condition.

Pattern: BFS.

Simple idea: The queue contains the next level. Read its current size before adding any children. That size tells you how many nodes belong to this level.

from __future__ import annotations
from collections import deque
from dataclasses import dataclass

@dataclass(eq=False, slots=True)
class TreeNode:
   val: int
   left: TreeNode | None = None
   right: TreeNode | None = None

def level_order(root: TreeNode | None) -> list[list[int]]:
   if root is None:
      return []

   answer: list[list[int]] = []
   queue = deque([root])

   while queue:
      level = []
      for _ in range(len(queue)):
         node = queue.popleft()
         level.append(node.val)
         if node.left:
            queue.append(node.left)
         if node.right:
            queue.append(node.right)
      answer.append(level)
   return answer

Cost: time and space, where is the widest level.