Simulation with Visited Matrix
Intuition
Simulate the spiral traversal by maintaining a visited matrix and a direction vector. Start moving right; when you hit a boundary or a visited cell, turn clockwise (right -> down -> left -> up). Continue until all cells are visited. This is an intuitive simulation approach that directly models the spiral movement.
Algorithm
- Create a visited matrix of the same dimensions, initialized to false.
- Define direction vectors for right, down, left, and up. Start with direction index 0 (right).
- Start at position (0, 0). Add the current element to the result and mark it as visited.
- Compute the next position. If it is out of bounds or already visited, change direction clockwise.
- Move to the next position and repeat until all m*n elements are collected.
O(m * n)SpaceO(m * n)Code (C++ · Java · Python · Go)
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int m = matrix.size(), n = matrix[0].size();
vector<vector<bool>> visited(m, vector<bool>(n, false));
int dr[] = {0, 1, 0, -1};
int dc[] = {1, 0, -1, 0};
vector<int> result;
int r = 0, c = 0, dir = 0;
for (int i = 0; i < m * n; i++) {
result.push_back(matrix[r][c]);
visited[r][c] = true;
int nr = r + dr[dir];
int nc = c + dc[dir];
if (nr < 0 || nr >= m || nc < 0 || nc >= n || visited[nr][nc]) {
dir = (dir + 1) % 4;
nr = r + dr[dir];
nc = c + dc[dir];
}
r = nr;
c = nc;
}
return result;
}
};class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
boolean[][] visited = new boolean[m][n];
int[] dr = {0, 1, 0, -1};
int[] dc = {1, 0, -1, 0};
List<Integer> result = new ArrayList<>();
int r = 0, c = 0, dir = 0;
for (int i = 0; i < m * n; i++) {
result.add(matrix[r][c]);
visited[r][c] = true;
int nr = r + dr[dir];
int nc = c + dc[dir];
if (nr < 0 || nr >= m || nc < 0 || nc >= n || visited[nr][nc]) {
dir = (dir + 1) % 4;
nr = r + dr[dir];
nc = c + dc[dir];
}
r = nr;
c = nc;
}
return result;
}
}def spiralOrder(matrix: list[list[int]]) -> list[int]:
m, n = len(matrix), len(matrix[0])
visited = [[False] * n for _ in range(m)]
dr = [0, 1, 0, -1]
dc = [1, 0, -1, 0]
result = []
r, c, d = 0, 0, 0
for _ in range(m * n):
result.append(matrix[r][c])
visited[r][c] = True
nr, nc = r + dr[d], c + dc[d]
if nr < 0 or nr >= m or nc < 0 or nc >= n or visited[nr][nc]:
d = (d + 1) % 4
nr, nc = r + dr[d], c + dc[d]
r, c = nr, nc
return resultfunc spiralOrder(matrix [][]int) []int {
m, n := len(matrix), len(matrix[0])
visited := make([][]bool, m)
for i := range visited {
visited[i] = make([]bool, n)
}
dr := []int{0, 1, 0, -1}
dc := []int{1, 0, -1, 0}
result := make([]int, 0, m*n)
r, c, dir := 0, 0, 0
for i := 0; i < m*n; i++ {
result = append(result, matrix[r][c])
visited[r][c] = true
nr := r + dr[dir]
nc := c + dc[dir]
if nr < 0 || nr >= m || nc < 0 || nc >= n || visited[nr][nc] {
dir = (dir + 1) % 4
nr = r + dr[dir]
nc = c + dc[dir]
}
r = nr
c = nc
}
return result
}