Skip to main content

17. Spiral Matrix

mediumAsked at Adobe

Return all elements of an m×n matrix in spiral order. Adobe's heavy focus on 2D array manipulation and image-buffer traversal makes this a recurring interview problem — spiral traversal is a canonical test of boundary-shrinking logic for pixel scan patterns.

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

Source citations

Public interview reports confirming this problem appears in Adobe loops.

  • Glassdoor (2025-11)Adobe SDE-II reports spiral matrix as a frequent onsite question tied to image traversal themes.
  • LeetCode Discuss (2026-01)Adobe candidates confirm spiral and other 2D traversal problems across multiple interview rounds.

Problem

Given an m x n matrix, return all elements of the matrix in spiral order starting from the top-left, moving right, then down, then left, then up, and continuing inward layer by layer.

Constraints

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100

Examples

Example 1

Input
matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output
[1,2,3,6,9,8,7,4,5]

Example 2

Input
matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
Output
[1,2,3,4,8,12,11,10,9,5,6,7]

Approaches

1. Visited matrix simulation

Use a boolean visited matrix and simulate the spiral direction-change logic.

Time
O(m*n)
Space
O(m*n)
function spiralOrder(matrix) {
  const m = matrix.length, n = matrix[0].length;
  const visited = Array.from({length: m}, () => Array(n).fill(false));
  const dirs = [[0,1],[1,0],[0,-1],[-1,0]];
  let d = 0, r = 0, c = 0;
  const result = [];
  for (let i = 0; i < m * n; i++) {
    result.push(matrix[r][c]);
    visited[r][c] = true;
    const [dr, dc] = dirs[d];
    const nr = r + dr, nc = c + dc;
    if (nr < 0 || nr >= m || nc < 0 || nc >= n || visited[nr][nc]) {
      d = (d + 1) % 4;
    }
    r += dirs[d][0];
    c += dirs[d][1];
  }
  return result;
}

Tradeoff: Correct but uses O(m*n) extra space for the visited matrix; Adobe expects the O(1) extra space boundary approach.

2. Layer-by-layer boundary shrink

Maintain four pointers: top, bottom, left, right. Traverse each boundary in order (top row left-to-right, right column top-to-bottom, bottom row right-to-left, left column bottom-to-top), then shrink boundaries inward. Handle single-row and single-column remnants carefully.

Time
O(m*n)
Space
O(1) extra
function spiralOrder(matrix) {
  const result = [];
  let top = 0, bottom = matrix.length - 1;
  let left = 0, right = matrix[0].length - 1;
  while (top <= bottom && left <= right) {
    for (let c = left; c <= right; c++) result.push(matrix[top][c]);
    top++;
    for (let r = top; r <= bottom; r++) result.push(matrix[r][right]);
    right--;
    if (top <= bottom) {
      for (let c = right; c >= left; c--) result.push(matrix[bottom][c]);
      bottom--;
    }
    if (left <= right) {
      for (let r = bottom; r >= top; r--) result.push(matrix[r][left]);
      left++;
    }
  }
  return result;
}

Tradeoff: O(m*n) time and O(1) extra space. The guard conditions for top <= bottom and left <= right before the left and bottom traversals prevent double-counting in non-square matrices.

Adobe-specific tips

Adobe interviewers watch for the guard conditions on the third and fourth traversals — missing them causes duplicate elements when the matrix has an odd number of rows or columns. Trace through a 3×1 matrix on the whiteboard to demonstrate you handle degenerate cases. Also be ready to discuss Spiral Matrix II (LC 59), which fills a matrix in spiral order.

Common mistakes

  • Missing the guard 'if (top <= bottom)' before traversing the bottom row, causing duplicate elements in non-square matrices.
  • Missing the guard 'if (left <= right)' before traversing the left column.
  • Incorrectly initializing boundary pointers or shrinking them in the wrong order.

Follow-up questions

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

  • Spiral Matrix II (LC 59): fill an n×n matrix in spiral order.
  • How would you traverse in counter-clockwise spiral?
  • How does this generalize to 3D arrays (spiral layer by layer)?

Solve it now

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

Output

Press Run or Cmd+Enter to execute

FAQ

Why do we need guards before the bottom-row and left-column traversals?

After incrementing top and decrementing right for the first two traversals, top may now exceed bottom (for a single-row or single-column remnant). Without the guard, we'd re-traverse already-collected elements.

Is there a direction-array approach that also works in O(1) space?

Yes — using direction arrays [0,1,1,0,0,-1,-1,0] and turning when hitting a boundary also works in O(1) space and is equivalent but slightly harder to read; the boundary-shrink approach is clearer for interviews.

Practice these live with InterviewChamp.AI

Drill Spiral Matrix and other Adobe interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →