54. Spiral Matrix
At a Glance
- Topic: arrays-hashing
- Pattern: Layered traversal
- Difficulty: Medium
- Companies: Amazon, Google, Meta, Microsoft, Apple
- Frequency: High
- LeetCode: 54
Problem (one-liner)
Given matrix with height rows and width columns, return all elements in clockwise spiral order starting from top-left.
Recognition Cues
- "Spiral order", "clockwise"
- Shrink boundaries: top, bottom, left, right after each edge sweep
Diagram
At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.
Loading diagram…
Approaches
- Brute force — simulate direction with visited map —
O(mn)time /O(mn)space. - Better — same without visited using layer shrinking —
O(1)extra. - Optimal — four boundaries while
top <= bottom && left <= right—O(mn)time /O(1)extra.
Optimal Solution
Go
package main
func spiralOrder(matrix [][]int) []int {
if len(matrix) == 0 {
return nil
}
height := len(matrix)
width := len(matrix[0])
result := make([]int, 0, height*width)
top := 0
bottom := height - 1
left := 0
right := width - 1
for top <= bottom && left <= right {
for col := left; col <= right; col++ {
result = append(result, matrix[top][col])
}
top++
for row := top; row <= bottom; row++ {
result = append(result, matrix[row][right])
}
right--
if top > bottom {
break
}
for col := right; col >= left; col-- {
result = append(result, matrix[bottom][col])
}
bottom--
if left > right {
break
}
for row := bottom; row >= top; row-- {
result = append(result, matrix[row][left])
}
left++
}
return result
}JavaScript
function spiralOrder(matrix) {
if (matrix.length === 0) {
return [];
}
const height = matrix.length;
const width = matrix[0].length;
const result = [];
let top = 0;
let bottom = height - 1;
let left = 0;
let right = width - 1;
while (top <= bottom && left <= right) {
for (let col = left; col <= right; col++) {
result.push(matrix[top][col]);
}
top++;
for (let row = top; row <= bottom; row++) {
result.push(matrix[row][right]);
}
right--;
if (top > bottom) {
break;
}
for (let col = right; col >= left; col--) {
result.push(matrix[bottom][col]);
}
bottom--;
if (left > right) {
break;
}
for (let row = bottom; row >= top; row--) {
result.push(matrix[row][left]);
}
left++;
}
return result;
}Walkthrough
matrix = [[1,2,3],[4,5,6],[7,8,9]]
| layer step | edge | appended values | bounds after |
|---|---|---|---|
| 1 | top row | 1,2,3 | top=1 |
| 2 | right col | 6,9 | right=1 |
| 3 | bottom row | 8,7 | bottom=1 |
| 4 | left col | 4 | left=1 |
| 5 | inner top | 5 | done |
Output [1,2,3,6,9,8,7,4,5].
Edge Cases
- Single row — only top sweep; watch duplicate vertical passes.
- Single column — similar symmetry breaks.
1×1matrix.
Pitfalls
- After shrinking top/right, inner row/column may be empty — need
top <= bottomchecks before vertical legs. - Off-by-one when advancing
topbefore right column.
Similar Problems
- 048. Rotate Image — matrix transformation.
- 036. Valid Sudoku — grid scanning.
- 189. Rotate Array — 1D circular walk analogue.
Variants
- Spiral Matrix II — fill
n×nby spiral. - Counter-clockwise — reverse edge order.
Mind-Map Tags
#matrix #spiral #layer #boundaries #simulation
Last updated on
Spotted something unclear or wrong on this page?