Traverse a Matrix in Spiral Order
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
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.
| 1 | class 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 |
0202Set the four boundaries to the matrix's edges: top=0, bottom=2, left=0, right=2.
Approach & Solutions
Brute Force
BruteWalk 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.
O(rows·cols)O(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
OptimalTrack 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.
O(rows·cols)O(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}