Problem statement
Given an m × n matrix, return all of its elements in spiral order: along the top row left to right, down the right column, back along the bottom row, up the left column, then repeat on the next ring inward.
Examples
- Input
matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
- Output
[1, 2, 3, 6, 9, 8, 7, 4, 5]
- 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]
- Input
matrix = [[1], [2], [3]]
- Output
[1, 2, 3]
Why: A single column must not be read twice.
Constraints
- 1 ≤ m, n ≤ 10
- −100 ≤ matrix[i][j] ≤ 100
How to answer it out loud
What it tests: Careful index management, loop invariants, and testing awkward shapes.
- 1Clarify
Clarify the matrix shape and whether it is always square.
- 2Implement
Keep four boundaries; read the top row, right column, bottom row and left column, then move the boundaries inward.
- 3Verify
Test a single row, a single column, a 1 × 1 matrix, and a non-square matrix; explain O(m·n) time.
From brute force to the best solution
| Approach | Idea | Time | Space |
|---|---|---|---|
| Direction simulation | Walk and turn right whenever the next cell is outside the grid or already visited. | O(m·n) | O(m·n) for visited |
| Shrinking boundariesBest | Keep top, bottom, left and right walls; read one ring, then move all four inward. | O(m·n) | O(1) extra |
The bugs live in the last ring. Only read the bottom row when it differs from the top row, and only read the left column when it differs from the right column.
Reference solution
Each version is self-contained and has been run against the examples and test cases on this page.
def spiral_order(matrix: list[list[int]]) -> list[int]: result = [] top, bottom = 0, len(matrix) - 1 left, right = 0, len(matrix[0]) - 1 while top <= bottom and left <= right: for c in range(left, right + 1): # top row, left -> right result.append(matrix[top][c]) for r in range(top + 1, bottom + 1): # right column, downwards result.append(matrix[r][right]) if top < bottom: # bottom row, if it is a new row for c in range(right - 1, left - 1, -1): result.append(matrix[bottom][c]) if left < right: # left column, if it is a new column for r in range(bottom - 1, top, -1): result.append(matrix[r][left]) top, bottom, left, right = top + 1, bottom - 1, left + 1, right - 1 return result- Time
- O(m·n)
- Space
- O(1) extra
- Approach
- Shrinking boundaries
Edge cases to run before you say “done”
| Input | Expected | Why it matters |
|---|---|---|
| [[1, 2, 3]] | [1, 2, 3] | A single row must not be read back. |
| [[1], [2], [3]] | [1, 2, 3] | A single column. |
| [[7]] | [7] | One cell. |
Answer the main question first, then take these on one at a time:
- Can you fill an n × n matrix with 1 to n² in spiral order?
- How would you walk the spiral counter-clockwise?
- Can you do it with a direction array instead of four loops?
Check your recording or written solution against this list:
- Reading the last row or column twice
- Off-by-one boundaries on non-square matrices
- Using a visited grid when boundaries are enough
This guide combines general interview-practice patterns with the public hiring material below. The practice prompt and coaching are PiriPiri AI editorial content, not official Microsoft questions or answers.
Official sources reviewed 20 September 2026.