Traverse a Matrix in Spiral Order

Solve this Problem
Medium20–25 min
Topics
Companies
Practice:GFG ↗
Given a matrix, return every element visited in spiral order — starting at the top-left, sweeping right across the top row, down the right column, left across the bottom row, up the left column, then spiraling inward and repeating until every cell has been visited. Tracking a visited grid works, but it wastes memory the traversal doesn't actually need: the boundary between "visited" and "unvisited" is always a clean rectangle shrinking inward, so four boundary pointers (top, bottom, left, right) are enough to know exactly which cells remain — no per-cell bookkeeping required.

Test Case 1:

Input:matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output:[1,2,3,6,9,8,7,4,5]
Explanation:Right across the top row, down the right column, left across the bottom row, up the remaining left column, then inward to the center.

Test Case 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]
Explanation:A non-square matrix works the same way — the boundaries just shrink at different rates for rows vs columns.

Test Case 3:

Input:matrix = [[7]]
Output:[7]
Explanation:A single cell is its own (trivial) spiral.

Constraints

  • 1 ≤ rows, cols ≤ 10
  • -100 ≤ matrix[i][j] ≤ 100
🚀

Try the Dry Run

Don't just read the solution — watch it execute, one step at a time.

🧪Try your own test case
1class Solution {
2 public int[] spiralOrder(int[][] matrix) {
3 int rows = matrix.length, cols = matrix[0].length;
4 int[] result = new int[rows * cols];
5 int idx = 0;
6 int top = 0, bottom = rows - 1, left = 0, right = cols - 1;
7 while (top <= bottom && left <= right) {
8 for (int j = left; j <= right; j++) result[idx++] = matrix[top][j];
9 top++;
10 for (int i = top; i <= bottom; i++) result[idx++] = matrix[i][right];
11 right--;
12 if (top <= bottom) {
13 for (int j = right; j >= left; j--) result[idx++] = matrix[bottom][j];
14 bottom--;
15 }
16 if (left <= right) {
17 for (int i = bottom; i >= top; i--) result[idx++] = matrix[i][left];
18 left++;
19 }
20 }
21 return result;
22 }
23}
24
Matrix
1
2
3
4
5
6
7
8
9
Array
Variables
top0
bottom2
left0
right2
INITIALIZE

Set the four boundaries to the matrix's edges: top=0, bottom=2, left=0, right=2.

Step 1 / 8

Approach & Solutions

Brute Force

Brute

Walk cell by cell, always trying to continue in the current direction (right, down, left, up, cycling in that order). Whenever the next cell would go out of bounds or has already been visited, turn to the next direction instead. Correct, but needs a full visited grid to know when to turn.

TimeO(rows·cols)
SpaceO(rows·cols)
1class Solution { 2 public int[] spiralOrder(int[][] matrix) { 3 int rows = matrix.length, cols = matrix[0].length; 4 boolean[][] visited = new boolean[rows][cols]; 5 int[] result = new int[rows * cols]; 6 int[] dr = {0, 1, 0, -1}; 7 int[] dc = {1, 0, -1, 0}; 8 int r = 0, c = 0, dir = 0; 9 for (int i = 0; i < rows * cols; i++) { 10 result[i] = matrix[r][c]; 11 visited[r][c] = true; 12 int nr = r + dr[dir], nc = c + dc[dir]; 13 if (nr < 0 || nr >= rows || nc < 0 || nc >= cols || visited[nr][nc]) { 14 dir = (dir + 1) % 4; 15 nr = r + dr[dir]; 16 nc = c + dc[dir]; 17 } 18 r = nr; 19 c = nc; 20 } 21 return result; 22 } 23}

Optimal — Shrinking Boundaries

Optimal

Track four boundaries — top, bottom, left, right. Traverse the top row left-to-right, the right column top-to-bottom, then (if a row remains) the bottom row right-to-left, then (if a column remains) the left column bottom-to-top — shrinking the corresponding boundary after each side. Repeat until the boundaries cross. No visited grid needed.

TimeO(rows·cols)
SpaceO(1)
1class Solution { 2 public int[] spiralOrder(int[][] matrix) { 3 int rows = matrix.length, cols = matrix[0].length; 4 int[] result = new int[rows * cols]; 5 int idx = 0; 6 int top = 0, bottom = rows - 1, left = 0, right = cols - 1; 7 while (top <= bottom && left <= right) { 8 for (int j = left; j <= right; j++) result[idx++] = matrix[top][j]; 9 top++; 10 for (int i = top; i <= bottom; i++) result[idx++] = matrix[i][right]; 11 right--; 12 if (top <= bottom) { 13 for (int j = right; j >= left; j--) result[idx++] = matrix[bottom][j]; 14 bottom--; 15 } 16 if (left <= right) { 17 for (int i = bottom; i >= top; i--) result[idx++] = matrix[i][left]; 18 left++; 19 } 20 } 21 return result; 22 } 23}

Related Problems