Spiral Matrix processes a matrix layer by layer, walking the outer boundary then moving inward:
Top → Right → Bottom → Left → Shrink → Repeat
Focus on recognizing:
“Spiral order” / “clockwise from outside in” → four boundaries + four directions
Core Template: Spiral Traversal
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>();
int top = 0;
int bottom = matrix.length - 1;
int left = 0;
int right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (int col = left; col <= right; col++) // → top row
result.add(matrix[top][col]);
top++;
for (int row = top; row <= bottom; row++) // ↓ right col
result.add(matrix[row][right]);
right--;
if (top <= bottom) { // ← bottom row
for (int col = right; col >= left; col--)
result.add(matrix[bottom][col]);
bottom--;
}
if (left <= right) { // ↑ left col
for (int row = bottom; row >= top; row--)
result.add(matrix[row][left]);
left++;
}
}
return result;
}def spiral_order(matrix):
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
result = []
while top <= bottom and left <= right:
for col in range(left, right + 1): # → top row
result.append(matrix[top][col])
top += 1
for row in range(top, bottom + 1): # ↓ right col
result.append(matrix[row][right])
right -= 1
if top <= bottom: # ← bottom row
for col in range(right, left - 1, -1):
result.append(matrix[bottom][col])
bottom -= 1
if left <= right: # ↑ left col
for row in range(bottom, top - 1, -1):
result.append(matrix[row][left])
left += 1
return resultvector<int> spiralOrder(vector<vector<int>>& matrix) {
int top = 0, bottom = matrix.size() - 1;
int left = 0, right = matrix[0].size() - 1;
vector<int> result;
while (top <= bottom && left <= right) {
for (int col = left; col <= right; col++) // → top row
result.push_back(matrix[top][col]);
top++;
for (int row = top; row <= bottom; row++) // ↓ right col
result.push_back(matrix[row][right]);
right--;
if (top <= bottom) { // ← bottom row
for (int col = right; col >= left; col--)
result.push_back(matrix[bottom][col]);
bottom--;
}
if (left <= right) { // ↑ left col
for (int row = bottom; row >= top; row--)
result.push_back(matrix[row][left]);
left++;
}
}
return result;
}function spiralOrder(matrix) {
let top = 0,
bottom = matrix.length - 1,
left = 0,
right = matrix[0].length - 1;
const result = [];
while (top <= bottom && left <= right) {
for (let col = left; col <= right; col++)
result.push(matrix[top][col]); // → top row
top++;
for (let row = top; row <= bottom; row++)
result.push(matrix[row][right]); // ↓ right col
right--;
if (top <= bottom) {
// ← bottom row
for (let col = right; col >= left; col--)
result.push(matrix[bottom][col]);
bottom--;
}
if (left <= right) {
// ↑ left col
for (let row = bottom; row >= top; row--)
result.push(matrix[row][left]);
left++;
}
}
return result;
}The two
ifguards before edges 3 and 4 prevent double-visiting when only one row or column remains.
Four variables (
top/bottom/left/right) own the current layer. Walk an edge, shrink its boundary.
Variant: Generate Spiral Matrix
Watch [1..9] unwind as 1 2 3 6 9 8 7 4 5 — each edge walked once, boundaries shrinking after each. Press ▶ to animate.
⚠️ Animation & Content Notice
The animation work is not fully finished — some animations may have slight errors.
If there is a major error in the content or if the animation or content is difficult to understand, please contact us at rayyancodingschool@gmail.com.
Spiral Traversal
Read a matrix in clockwise spiral order using four shrinking boundaries (top, bottom, left, right). Each edge is consumed, then the boundary moves inward.
Matrix: [[1,2,3],[4,5,6],[7,8,9]]. Top row → right column → bottom row (reverse) → left column (reverse), then repeat on the inner layer. The highlighted cells are the edge being consumed; the state chips track the live boundaries (top/bottom/left/right).
1
top=0, bottom=rows-1, left=0, right=cols-1
2
while top <= bottom && left <= right:
3
left→right along top row; top++
4
top→bottom along right col; right--
5
right→left along bottom row; bottom--
6
bottom→top along left col; left++
Same boundary walk — but write values instead of reading them:
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int top = 0, bottom = n - 1, left = 0, right = n - 1;
int value = 1;
while (top <= bottom && left <= right) {
for (int col = left; col <= right; col++)
matrix[top][col] = value++;
top++;
for (int row = top; row <= bottom; row++)
matrix[row][right] = value++;
right--;
if (top <= bottom) {
for (int col = right; col >= left; col--)
matrix[bottom][col] = value++;
bottom--;
}
if (left <= right) {
for (int row = bottom; row >= top; row--)
matrix[row][left] = value++;
left++;
}
}
return matrix;
}def generate_matrix(n):
matrix = [[0] * n for _ in range(n)]
top, bottom, left, right = 0, n - 1, 0, n - 1
value = 1
while top <= bottom and left <= right:
for col in range(left, right + 1):
matrix[top][col] = value
value += 1
top += 1
for row in range(top, bottom + 1):
matrix[row][right] = value
value += 1
right -= 1
if top <= bottom:
for col in range(right, left - 1, -1):
matrix[bottom][col] = value
value += 1
bottom -= 1
if left <= right:
for row in range(bottom, top - 1, -1):
matrix[row][left] = value
value += 1
left += 1
return matrixvector<vector<int>> generateMatrix(int n) {
vector<vector<int>> matrix(n, vector<int>(n));
int top = 0, bottom = n - 1, left = 0, right = n - 1;
int value = 1;
while (top <= bottom && left <= right) {
for (int col = left; col <= right; col++)
matrix[top][col] = value++;
top++;
for (int row = top; row <= bottom; row++)
matrix[row][right] = value++;
right--;
if (top <= bottom) {
for (int col = right; col >= left; col--)
matrix[bottom][col] = value++;
bottom--;
}
if (left <= right) {
for (int row = bottom; row >= top; row--)
matrix[row][left] = value++;
left++;
}
}
return matrix;
}function generateMatrix(n) {
const matrix = Array.from({ length: n }, () => Array(n).fill(0));
let top = 0,
bottom = n - 1,
left = 0,
right = n - 1,
value = 1;
while (top <= bottom && left <= right) {
for (let col = left; col <= right; col++) matrix[top][col] = value++;
top++;
for (let row = top; row <= bottom; row++) matrix[row][right] = value++;
right--;
if (top <= bottom) {
for (let col = right; col >= left; col--)
matrix[bottom][col] = value++;
bottom--;
}
if (left <= right) {
for (let row = bottom; row >= top; row--)
matrix[row][left] = value++;
left++;
}
}
return matrix;
}Counter-clockwise variant: same skeleton with the direction order rotated (
↑ → ↓ ←) or the matrix transposed afterwards.
Common Mistakes
Missing the single-row/single-column guards.
Without if (top <= bottom) / if (left <= right), rectangular matrices get cells visited twice on the last layer.
Shrinking at the wrong time.
Increment top only AFTER walking the top row — shrink-as-you-go keeps each edge’s range correct.
Hardcoding square matrices.
m × n works fine with four independent boundaries — don’t assume n × n.
Complexity
| Operation | Time | Space |
|---|---|---|
| Traverse | O(n·m) | O(1) extra |
| Generate | O(n²) | O(n²) output |
Premium Content
Unlock Spiral Matrix and all premium lessons with a subscription.
From ₹199.99/year — See plans