Given the root of a binary tree, return an array of the largest value in each row.

Engineering takeaway. "Each row of a tree" is almost a definition of BFS — process one level, then the next. But DFS with an explicit level counter is equally valid and often more flexible (think: recursive components, HTML rendering, tree serializers). Knowing both traversals and when to reach for each is core senior-level fluency.

Intuition

Two mental models:

  • BFS walks the tree level by level. Each level is literally a "row", so finding the max per level is natural.
  • DFS walks depth-first but carries a level argument. We keep an array indexed by level and update the max as we go.

Approach — BFS

  1. Start a queue with the root.
  2. For each level: find the max among all nodes in the queue, then push all their children into the next queue.
  3. Repeat until no nodes remain.
function largestValues(root: TreeNode | null): number[] {
  if (root === null) return [];
 
  const result: number[] = [];
  let level: TreeNode[] = [root];
 
  while (level.length > 0) {
    let max = Number.NEGATIVE_INFINITY;
    const next: TreeNode[] = [];
 
    for (const node of level) {
      max = Math.max(max, node.val);
      if (node.left) next.push(node.left);
      if (node.right) next.push(node.right);
    }
 
    result.push(max);
    level = next;
  }
 
  return result;
}

Approach — DFS

  1. Recurse with (node, level).
  2. If result[level] is unset, set it to node.val; otherwise take the max.
  3. Recurse into children at level + 1.
function largestValues(root: TreeNode | null): number[] {
  const result: number[] = [];
 
  const dfs = (node: TreeNode | null, level: number): void => {
    if (node === null) return;
 
    if (result[level] === undefined) {
      result[level] = node.val;
    } else {
      result[level] = Math.max(result[level], node.val);
    }
 
    dfs(node.left, level + 1);
    dfs(node.right, level + 1);
  };
 
  dfs(root, 0);
  return result;
}

Complexity

  • Time: O(n) — every node is visited once in both approaches.
  • Space: BFS O(w) where w is the widest level; DFS O(h) for the call stack.

The lesson

When the problem is organized around depth, BFS gives you the level for free but carries memory for the whole frontier; DFS costs you a stack but only as deep as the tree. For "per-level" problems both work — pick based on which resource you want to trade.