Medium Matrix Simulation

54. Spiral Matrix

LC
Practice this algorithm on LeetCode to reinforce your understanding.
Open Problem

Traverse a matrix in clockwise spiral order — O(m·n) time · O(1) extra space

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
💡 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

StepActionPositionValueDirectiontop/bot/left/rightOutput 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

📝 Notes ✅

▼
===== -->