medium

Spiral Matrix

Return every element of a matrix in spiral order.

1. Define the problem

Spiral Matrix

Given an m x n matrix, return all elements of the matrix in spiral order : starting at the top-left corner, walk across the top row, down the right column, across the bottom row, and up the left column, then shrink inward and repeat. Track four moving boundaries (top, bottom, left, right) and peel off one full ring of the matrix per lap, tightening the boundaries after each side.

Constraints

  • m == matrix.length
  • n == matrixi.length
  • 1 ≤ m, n ≤ 10
  • -100 ≤ matrixi[j] ≤ 100

Example

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

Explanation Walk the top row left-to-right, the right column top-to-bottom, the bottom row right-to-left, the left column bottom-to-top, then spiral into the single remaining center cell.

2. Know the words first

In plain terms

Boundaries
The four edges of the part of the matrix not yet visited — they shrink inward by one every time a side is fully walked.
3. Visualize the solution

Peel off one ring at a time, shrinking inward

Peel off one ring at a time, shrinking inward
Statustop-row

Walk the top row: push 1, 2, 3. Move the top boundary down.

What happens in this step

top=0, bottom=2, left=0, right=2
Walk columns 0..2 of row 0: push 1, 2, 3
result = [1, 2, 3]
top becomes 1
Step 1 of 6

Steps to visualize

  1. Walk the top row from the left boundary to the right boundary, then move the top boundary down.
  2. Walk the right column from the new top boundary to the bottom boundary, then move the right boundary in.
  3. If a row remains, walk the bottom row from the right boundary to the left boundary, then move the bottom boundary up.
  4. If a column remains, walk the left column from the bottom boundary to the top boundary, then move the left boundary in.
  5. Repeat until the boundaries cross — every cell has now been visited exactly once.
4. Walk through the code

Walk through the code

Same walkthrough, now with the code. Press Next to move one step and watch which lines run.

Peel off one ring at a time, shrinking inward
Statustop-row

Walk the top row: push 1, 2, 3. Move the top boundary down.

What happens in this step

top=0, bottom=2, left=0, right=2
Walk columns 0..2 of row 0: push 1, 2, 3
result = [1, 2, 3]
top becomes 1
Step 1 of 6
5. Solution

Solution

solution.tsTypeScript
function spiralOrder(matrix) {
  const result = [];
  let top = 0;
  let bottom = matrix.length - 1;
  let left = 0;
  let right = matrix[0].length - 1;

  while (top <= bottom && left <= right) {
    for (let col = left; col <= right; col++) {
      result.push(matrix[top][col]);
    }
    top++;

    for (let row = top; row <= bottom; row++) {
      result.push(matrix[row][right]);
    }
    right--;

    if (top <= bottom) {
      for (let col = right; col >= left; col--) {
        result.push(matrix[bottom][col]);
      }
      bottom--;
    }

    if (left <= right) {
      for (let row = bottom; row >= top; row--) {
        result.push(matrix[row][left]);
      }
      left++;
    }
  }

  return result;
}
Time
O(m * n)
Space
O(1) (excluding the output array)
6. Test cases

Test cases

InputExpectedCovers
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]][1, 2, 3, 6, 9, 8, 7, 4, 5]example from the docstring
matrix = [[1]][1]smallest valid input: a single cell
matrix = [[1, 2, 3, 4]][1, 2, 3, 4]a matrix with only one row
matrix = [[1], [2], [3]][1, 2, 3]a matrix with only one column
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]][1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]a rectangular matrix with more columns than rows
matrix = [[1, 2], [3, 4]][1, 2, 4, 3]smallest matrix that actually turns a corner