What does it solve?
Given an m × n matrix, return all elements in clockwise spiral order — starting top-left, going right → down → left → up, then peeling inward one layer at a time.
Example: [[1,2,3],[4,5,6],[7,8,9]] → [1,2,3,6,9,8,7,4,5]
Shrinking boundaries
// 4 walls shrink after each direction
top=0, bottom=m-1, left=0, right=n-1
→ Right: top row → top++
↓ Down: right col → right--
← Left: bottom row → bottom--
↑ Up: left col → left++
// repeat until boundaries cross
top=0, bottom=m-1, left=0, right=n-1
→ Right: top row → top++
↓ Down: right col → right--
← Left: bottom row → bottom--
↑ Up: left col → left++
// repeat until boundaries cross
💡 Key insight: Think of the matrix as nested rectangular rings. After traversing one complete ring (right → down → left → up), shrink all four boundaries inward by 1. The traversal ends when
top > bottom or left > right. The write pointer and read pointer (boundaries) never conflict — making this O(1) space.
Complexity
Time
O(m·n)
Every cell is visited exactly once — one element added to result per step.
Space
O(1)
Only four boundary variables. Output array not counted as extra space.
Examples & edge cases
Live animation — Shrinking Boundaries
→ Right
↓ Down
← Left
↑ Up
Current cell
⏸ Waiting
Matrix — boundaries shown as border
Spiral output — elements collected
Empty — press Play
top ↓
—
bottom ↑
—
left →
—
right ←
—
Step — of —
Position
—
row, col
Direction
—
—
Collected
0
of — cells
Layer
—
spiral ring
Select an example and press Play to begin.
✓ Done!
Speed
Medium
Step-by-step table
| Step | Action | Position | Value | Direction | top/bot/left/right | Output so far |
|---|
C++ implementation
spiral_matrix.cpp
#include <bits/stdc++.h> using namespace std; vector<int> spiralOrder(vector<vector<int>>& matrix) { vector<int> result; int top = 0, bottom = matrix.size() - 1; int left = 0, right = matrix[0].size() - 1; while (top <= bottom && left <= right) { // → Traverse right along top row for (int col = left; col <= right; col++) result.push_back(matrix[top][col]); top++; // ↓ Traverse down along right column for (int row = top; row <= bottom; row++) result.push_back(matrix[row][right]); right--; // ← Traverse left along bottom row (if still valid) if (top <= bottom) { for (int col = right; col >= left; col--) result.push_back(matrix[bottom][col]); bottom--; } // ↑ Traverse up along left column (if still valid) if (left <= right) { for (int row = bottom; row >= top; row--) result.push_back(matrix[row][left]); left++; } } return result; } int main() { vector<vector<int>> matrix = {{1,2,3},{4,5,6},{7,8,9}}; auto res = spiralOrder(matrix); // [1,2,3,6,9,8,7,4,5] for (int x : res) cout << x << " "; }
My Notes