Spiral Matrix — Solution in Python, Java & C++
Spiral Matrix solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A medium problem on arrays and matrix.
Spiral Matrix is a medium coding problem on arrays, matrix and simulation, asked in Morgan Stanley, Capital One, Databricks and Nutanix interviews.
- Difficulty: Medium
- Topics: Arrays, Matrix, Simulation
- Asked at: Morgan Stanley, Capital One, Databricks, Nutanix, Yahoo, Epic Systems, Hulu, LiveRamp
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
Given an m x n matrix, return all its elements in spiral order (clockwise from the top-left).
Example 1
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [1,2,3,6,9,8,7,4,5]
Example 2
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]
Constraints
1 <= m, n <= 8-100 <= matrix[i][j] <= 100
Hints for Spiral Matrix
Hint 1
Maintain four boundaries: top, bottom, left, right.
Hint 2
Walk each edge, then shrink that boundary; re-check bounds before the bottom and left passes.
How to solve Spiral Matrix
Track the four edges of the unvisited rectangle — top, bottom, left, right — and peel one edge at a time: across the top, down the right, back along the bottom, up the left. After each pass, pull that boundary inward. The rectangle shrinks until nothing is left.
Approach
- Initialise
top = 0,bottom = rows - 1,left = 0,right = cols - 1. - Walk left to right along
top, then incrementtop. - Walk top to bottom along
right, then decrementright. - If
top <= bottom, walk right to left alongbottom, then decrementbottom. - If
left <= right, walk bottom to top alongleft, then incrementleft. Repeat while the rectangle is non-empty.
Why it works
Each pass consumes exactly one full edge of the remaining rectangle and then removes that line from consideration, so no cell is ever visited twice and the region strictly shrinks — guaranteeing termination after all rows · cols cells. The two re-checks matter because a single remaining row or column would otherwise be traversed twice: once by the top pass and again by the bottom pass.
Complexity
- Time —
O(rows · cols) - Space —
O(1) beyond the output
Pitfalls
- The bounds re-check before the bottom and left passes is essential — without it, a one-row or one-column matrix emits duplicate values.
- Update each boundary immediately after its pass, not all four at the end.
- The outer loop condition must cover both dimensions (
top <= bottom && left <= right). - Non-square matrices are the common failure case; test a single row and a single column.
Reference solution
Python
from typing import List
def spiralOrder(matrix: List[List[int]]) -> List[int]:
out = []
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
while top <= bottom and left <= right:
for j in range(left, right + 1):
out.append(matrix[top][j])
top += 1
for i in range(top, bottom + 1):
out.append(matrix[i][right])
right -= 1
if top <= bottom:
for j in range(right, left - 1, -1):
out.append(matrix[bottom][j])
bottom -= 1
if left <= right:
for i in range(bottom, top - 1, -1):
out.append(matrix[i][left])
left += 1
return outJava
public static int[] spiralOrder(int[][] matrix) {
List<Integer> out = new ArrayList<>();
int top = 0, bottom = matrix.length - 1, left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (int j = left; j <= right; j++) out.add(matrix[top][j]);
top++;
for (int i = top; i <= bottom; i++) out.add(matrix[i][right]);
right--;
if (top <= bottom) {
for (int j = right; j >= left; j--) out.add(matrix[bottom][j]);
bottom--;
}
if (left <= right) {
for (int i = bottom; i >= top; i--) out.add(matrix[i][left]);
left++;
}
}
int[] res = new int[out.size()];
for (int i = 0; i < out.size(); i++) res[i] = out.get(i);
return res;
}C++
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> out;
int top = 0, bottom = (int) matrix.size() - 1, left = 0, right = (int) matrix[0].size() - 1;
while (top <= bottom && left <= right) {
for (int j = left; j <= right; j++) out.push_back(matrix[top][j]);
top++;
for (int i = top; i <= bottom; i++) out.push_back(matrix[i][right]);
right--;
if (top <= bottom) {
for (int j = right; j >= left; j--) out.push_back(matrix[bottom][j]);
bottom--;
}
if (left <= right) {
for (int i = bottom; i >= top; i--) out.push_back(matrix[i][left]);
left++;
}
}
return out;
}JavaScript
var spiralOrder = function(matrix) {
const out = [];
let top = 0, bottom = matrix.length - 1;
let left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (let j = left; j <= right; j++) out.push(matrix[top][j]);
top++;
for (let i = top; i <= bottom; i++) out.push(matrix[i][right]);
right--;
if (top <= bottom) {
for (let j = right; j >= left; j--) out.push(matrix[bottom][j]);
bottom--;
}
if (left <= right) {
for (let i = bottom; i >= top; i--) out.push(matrix[i][left]);
left++;
}
}
return out;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 1199 arrays problems · the whole catalogue
Learn the technique: Arrays · Matrix and Grid Traversal