Skip to main content

102. Binary Tree Level Order Traversal

mediumAsked at Atlassian

Binary Tree Level Order Traversal is the canonical Atlassian BFS-on-a-tree problem. Return the nodes' values level by level (left to right, one array per level). Atlassian uses it to confirm you can write BFS without smearing levels together.

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Source citations

Public interview reports confirming this problem appears in Atlassian loops.

  • Glassdoor (2026-Q1)Atlassian SWE-II onsite reports cite Level Order Traversal as the BFS warm-up before more complex tree problems.
  • Blind (2025-09)Atlassian threads list this as the canonical tree-BFS opener with predictable follow-ups (zigzag, right-side view).

Problem

Given the root of a binary tree, return the level order traversal of its nodes' values (i.e., from left to right, level by level).

Constraints

  • The number of nodes in the tree is in the range [0, 2000].
  • -1000 <= Node.val <= 1000

Examples

Example 1

Input
root = [3,9,20,null,null,15,7]
Output
[[3],[9,20],[15,7]]

Example 2

Input
root = [1]
Output
[[1]]

Example 3

Input
root = []
Output
[]

Approaches

1. BFS with level-size snapshot (canonical)

Use a queue. At each step capture the current queue length as the level size, then pop that many nodes into the level array; enqueue their children.

Time
O(n)
Space
O(n)
function levelOrder(root) {
  if (!root) return [];
  const result = [];
  const queue = [root];
  while (queue.length) {
    const size = queue.length;
    const level = [];
    for (let i = 0; i < size; i++) {
      const node = queue.shift();
      level.push(node.val);
      if (node.left) queue.push(node.left);
      if (node.right) queue.push(node.right);
    }
    result.push(level);
  }
  return result;
}

Tradeoff: The Atlassian-canonical answer. The size-snapshot is the load-bearing trick — without it you'd need to enqueue sentinel nulls or zip parent levels onto children. queue.shift() is O(n) in JS arrays; for the 2000-node constraint it's fine, but mention the head-pointer optimization.

2. DFS with explicit depth

Recurse with depth; append node.val to result[depth] (create the inner array on first visit).

Time
O(n)
Space
O(h) recursion
function levelOrderDFS(root) {
  const result = [];
  const dfs = (node, depth) => {
    if (!node) return;
    if (result.length === depth) result.push([]);
    result[depth].push(node.val);
    dfs(node.left, depth + 1);
    dfs(node.right, depth + 1);
  };
  dfs(root, 0);
  return result;
}

Tradeoff: Shorter but the BFS version is more defensible — DFS happens to work here because we visit left-before-right, but it doesn't generalize to 'process node only after seeing the full level' which the BFS version supports naturally. Use BFS; mention DFS as an alternative.

Atlassian-specific tips

Atlassian interviewers almost always follow up with one of: Zigzag Level Order (reverse alternate levels), Binary Tree Right Side View (last node per level), or Level Order Bottom-Up (reverse the result). All three are 1-line changes to the BFS version. The DFS version generalizes less cleanly; lead with BFS so the follow-ups are quick.

Common mistakes

  • Forgetting the level-size snapshot — mixing nodes from different levels into the same inner array.
  • Pushing children before reading the val — usually harmless but breaks if you mutate the tree.
  • Returning [] for an empty tree but [[ ]] for a single null in result — read the spec's expected output (empty array, not [[ ]]).

Follow-up questions

An interviewer at Atlassian may pivot to one of these next:

  • Binary Tree Zigzag Level Order Traversal (LeetCode 103) — reverse every other level.
  • Binary Tree Right Side View (LeetCode 199) — last node per level.
  • Average of Levels in Binary Tree (LeetCode 637) — sum/count per level.

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

FAQ

BFS or DFS at Atlassian?

BFS. It's the natural fit, generalizes cleanly to all the level-themed follow-ups, and avoids stack-overflow risk on deep trees.

Why size-snapshot instead of sentinel nulls?

Sentinels work but waste memory and add a control-flow branch (check for sentinel vs node). The size-snapshot reads more cleanly and is what production code uses. Atlassian's rubric rewards the cleaner pattern.

Free learning resources

Curated free links for this problem.

Practice these live with InterviewChamp.AI

Drill Binary Tree Level Order Traversal and other Atlassian interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →