Spiral Matrix

MediumMatrix · Simulation🧩 Matrix TraversalLeetCode #54 ↗Updated

Problem

Given an m × n matrix, return all of its elements in clockwise spiral order: start at the top-left, go right along the top row, down the right column, left along the bottom row, up the left column, then repeat on the inner ring.
Input[[1,2,3],[4,5,6],[7,8,9]]Output[1,2,3,6,9,8,7,4,5]
Input[[1,2,3,4],[5,6,7,8]]Output[1,2,3,4,8,7,6,5]

1 ≤ m, n ≤ 10  ·  -100 ≤ matrix[i][j] ≤ 100

Try it yourself

Java
class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Peel the matrix like an onion: keep four shrinking boundaries top, bottom, left, right. After each side is walked, move that boundary inward; stop when they cross.
PatternMatrix Traversal

Instinct A 2D grid you must walk in a fixed geometric order (spiral, diagonal, layer, rotate) or update in place - think boundaries, direction vectors and index maths.

Memory hack Walk the walls, then shrink the room - four fences (top, bottom, left, right) close in after every lap.

Open the Matrix Traversal guide →

Approaches

Brute ForceDirection Simulation + Visited Grid

Time O(m·n)Space O(m·n)

Walk like a robot with direction vectors right → down → left → up. Mark each cell in visited; if the next step leaves the grid or hits a visited cell, turn clockwise. Exactly m·n steps.

Java
public List<Integer> spiralOrder(int[][] matrix) {
    List<Integer> result = new ArrayList<>();
    int m = matrix.length, n = matrix[0].length;
    boolean[][] visited = new boolean[m][n];
    int[] dr = {0, 1, 0, -1}, dc = {1, 0, -1, 0}; // right, down, left, up
    int r = 0, c = 0, d = 0;
    for (int k = 0; k < m * n; k++) {
        result.add(matrix[r][c]);
        visited[r][c] = true;
        int nr = r + dr[d], nc = c + dc[d];
        if (nr < 0 || nr >= m || nc < 0 || nc >= n || visited[nr][nc]) {
            d = (d + 1) % 4; // blocked: turn clockwise
            nr = r + dr[d];
            nc = c + dc[d];
        }
        r = nr;
        c = nc;
    }
    return result;
}

Hard to get wrong, but needs an extra m×n boolean grid.

At a glance

LevelApproachTimeSpace
Brute ForceDirection Simulation + Visited GridO(m·n)O(m·n)
OptimalLayer-by-Layer BoundariesO(m·n)O(1)
Common pitfalls
  • Dropping the top ≤ bottom / left ≤ right guards — duplicates on non-square input.
  • Turning on the visited check but forgetting the bounds check (or vice versa).
  • Swapping row/column indices — matrix[row][col], rows = matrix.length.
Interview tips
  • Draw the four boundaries and say which one moves after each side.
  • Mention the follow-on: Spiral Matrix II fills the same path with 1..n2.
  • Prove termination: each full lap removes at least one row or column.
Pattern
Boundary-shrinking simulation → traverse or fill a grid ring by ring (spiral, rotate layers).
My notes saved in this browser