Skip to content

Spiral Matrix

Given an m x n matrix, return all elements of the matrix in spiral order (clockwise, starting from the top-left corner).

A spiral order means: move right along the top row, then down along the right column, then left along the bottom row, then up along the left column, and repeat for inner layers.

MatrixOutputExplanation
[[1,2,3],[4,5,6],[7,8,9]][1,2,3,6,9,8,7,4,5]Right → Down → Left → Up (spiral inward)
[[1,2,3,4],[5,6,7,8],[9,10,11,12]][1,2,3,4,8,12,11,10,9,5,6,7]Same spiral pattern on a 3x4 matrix
[[1]][1]Single element returns itself
[[1,2],[3,4]][1,2,4,3]2x2 matrix: right, down, left
  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100
ApproachTimeSpaceBest When
Simulation with BoundariesO(m * n)O(1)*Easiest to understand and implement
Layer-by-LayerO(m * n)O(1)*Conceptually cleaner, similar performance

* Excluding the output list.

  • Pick Simulation with Boundaries if you prefer explicit control of four directions and shrinking edges.
  • Pick Layer-by-Layer if you prefer thinking in terms of concentric rectangles or “peeling” the matrix.

Both have identical time and space complexity — choose based on mental model preference.

Most Intuitive
Simulation with Boundaries
O(m * n) time · O(1) space
Layer Thinking
Layer-by-Layer
O(m * n) time · O(1) space
Section titled “Approach 1: Simulation with Boundaries (Recommended)”
★ Recommended

Maintain four boundaries: top, bottom, left, and right. Traverse in four directions (right, down, left, up), shrinking the appropriate boundary after each direction. Repeat until all cells are visited.

This approach is the most direct and easiest to visualize—you literally simulate the spiral motion.

⏱ Time O(m * n) Visit each cell once 💾 Space O(1) No extra data structures

Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]

Initial boundaries: top=0, bottom=2, left=0, right=2

StepDirectionCells AddedBoundary UpdateDescription
1Right1, 2, 3top=1Traverse row 0 left-to-right
2Down6, 9right=1Traverse column 2 top-to-bottom
3Left8, 7bottom=1Traverse row 2 right-to-left
4Up4left=1Traverse column 0 bottom-to-top
5Right5top=1Center element (last layer)

Final Output: [1, 2, 3, 6, 9, 8, 7, 4, 5]

Animated walkthrough

How spiral traversal works with boundary shrinking

Watch the boundaries (top, bottom, left, right) shrink as you spiral inward. Each direction adds cells to the result and updates a boundary.

Step 1 of 5
Waiting to begin...
Array state
Memory / lookup state

function spiralMatrixSimulation(matrix):
if matrix is empty:
return []
result = []
top = 0, bottom = rows - 1
left = 0, right = cols - 1
while top <= bottom and left <= right:
// Traverse right
for col in [left, right]:
result.append(matrix[top][col])
top += 1
// Traverse down
for row in [top, bottom]:
result.append(matrix[row][right])
right -= 1
// Traverse left (if row remains)
if top <= bottom:
for col in [right, left] reversed:
result.append(matrix[bottom][col])
bottom -= 1
// Traverse up (if column remains)
if left <= right:
for row in [bottom, top] reversed:
result.append(matrix[row][left])
left += 1
return result
spiral_matrix_simulation.py
from typing import List
def spiral_matrix_simulation(matrix: List[List[int]]) -> List[int]:
"""
Traverse the matrix in spiral order using boundary tracking.
Time Complexity: O(m * n) where m is rows and n is columns
Space Complexity: O(1) excluding the result list
"""
if not matrix or not matrix[0]:
return []
result = []
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
while top <= bottom and left <= right:
# Traverse right
for col in range(left, right + 1):
result.append(matrix[top][col])
top += 1
# Traverse down
for row in range(top, bottom + 1):
result.append(matrix[row][right])
right -= 1
# Traverse left (if there's a row remaining)
if top <= bottom:
for col in range(right, left - 1, -1):
result.append(matrix[bottom][col])
bottom -= 1
# Traverse up (if there's a column remaining)
if left <= right:
for row in range(bottom, top - 1, -1):
result.append(matrix[row][left])
left += 1
return result
# Test cases
print(spiral_matrix_simulation([[1, 2, 3], [4, 5, 6], [7, 8, 9]])) # [1, 2, 3, 6, 9, 8, 7, 4, 5]
print(spiral_matrix_simulation([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])) # [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]
🎯 Interview Favourite

Instead of thinking in terms of four directions and shrinking boundaries, think of the matrix as concentric rectangular layers. Process each layer from outside to inside, treating each layer as a rectangle.

This approach is conceptually equivalent to Approach 1 but organizes the logic around layers rather than directions.

⏱ Time O(m * n) Visit each cell once 💾 Space O(1) No extra data structures

Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]

Layers: layer 0 (outer) and layer 1 (inner/center)

LayerElementsDescription
0[1, 2, 3, 6, 9, 8, 7, 4]Outer rectangle perimeter
1[5]Center element (innermost layer)

Final Output: [1, 2, 3, 6, 9, 8, 7, 4, 5]

The number of layers is (min(m, n) + 1) / 2. For a 3x3 matrix, that’s (3 + 1) / 2 = 2 layers.

function spiralMatrixLayer(matrix):
if matrix is empty:
return []
result = []
m, n = rows, cols
layers = (min(m, n) + 1) / 2
for layer in [0, layers):
top = layer
bottom = m - 1 - layer
left = layer
right = n - 1 - layer
// Traverse right
for col in [left, right]:
result.append(matrix[top][col])
// Traverse down
for row in [top+1, bottom]:
result.append(matrix[row][right])
// Traverse left (if row remains)
if top < bottom:
for col in [right-1, left] reversed:
result.append(matrix[bottom][col])
// Traverse up (if column remains)
if left < right:
for row in [bottom-1, top+1] reversed:
result.append(matrix[row][left])
return result
spiral_matrix_layer.py
from typing import List
def spiral_matrix_layer(matrix: List[List[int]]) -> List[int]:
"""
Traverse the matrix in spiral order by peeling off layers.
Time Complexity: O(m * n) where m is rows and n is columns
Space Complexity: O(1) excluding the result list
"""
if not matrix or not matrix[0]:
return []
result = []
m, n = len(matrix), len(matrix[0])
layers = (min(m, n) + 1) // 2
for layer in range(layers):
top = layer
bottom = m - 1 - layer
left = layer
right = n - 1 - layer
# Traverse right
for col in range(left, right + 1):
result.append(matrix[top][col])
# Traverse down
for row in range(top + 1, bottom + 1):
result.append(matrix[row][right])
# Traverse left (if there's a row remaining)
if top < bottom:
for col in range(right - 1, left - 1, -1):
result.append(matrix[bottom][col])
# Traverse up (if there's a column remaining)
if left < right:
for row in range(bottom - 1, top, -1):
result.append(matrix[row][left])
return result
# Test cases
print(spiral_matrix_layer([[1, 2, 3], [4, 5, 6], [7, 8, 9]])) # [1, 2, 3, 6, 9, 8, 7, 4, 5]
print(spiral_matrix_layer([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])) # [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
spiral_matrix_space_optimized.py
"""
Solution for Spiral Matrix
"""
def solve():
"""Implementation for approach 3 of Spiral Matrix"""
pass
if __name__ == "__main__":
print("Solution ready")