50. Spiral Matrix
mediumAsked at SnowflakeTraverse an m x n matrix in spiral order. Snowflake asks this to test boundary tracking — relevant for windowing operations over multi-dimensional storage layouts.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Snowflake loops.
- Glassdoor (2025-Q4)— Snowflake new-grad onsite as a boundary-tracking test.
- LeetCode Discuss (2025-09)— Reported at Snowflake SDE-I screens.
Problem
Given an m x n matrix, return all elements of the matrix in spiral order.
Constraints
m == matrix.lengthn == matrix[i].length1 <= m, n <= 10-100 <= matrix[i][j] <= 100
Examples
Example 1
matrix = [[1,2,3],[4,5,6],[7,8,9]][1,2,3,6,9,8,7,4,5]Example 2
matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]][1,2,3,4,8,12,11,10,9,5,6,7]Approaches
1. Direction array with visited set
Walk in directions (right, down, left, up). Rotate direction on bounds or visited cell.
- Time
- O(mn)
- Space
- O(mn) for visited
function spiralOrder(matrix) {
const m = matrix.length, n = matrix[0].length;
const result = [];
const seen = new Array(m).fill(null).map(() => new Array(n).fill(false));
const dirs = [[0,1],[1,0],[0,-1],[-1,0]];
let r = 0, c = 0, d = 0;
for (let i = 0; i < m * n; i++) {
result.push(matrix[r][c]);
seen[r][c] = true;
const nr = r + dirs[d][0], nc = c + dirs[d][1];
if (nr < 0 || nr >= m || nc < 0 || nc >= n || seen[nr][nc]) {
d = (d + 1) % 4;
}
r += dirs[d][0];
c += dirs[d][1];
}
return result;
}Tradeoff: O(mn) extra space for the seen matrix.
2. Four shrinking boundaries (optimal)
Track top, bottom, left, right. Walk right along top, down along right, left along bottom (if bottom > top), up along left (if right > left). Shrink boundaries after each side.
- Time
- O(mn)
- Space
- O(1)
function spiralOrder(matrix) {
const result = [];
let top = 0, bottom = matrix.length - 1, left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (let c = left; c <= right; c++) result.push(matrix[top][c]);
top++;
for (let r = top; r <= bottom; r++) result.push(matrix[r][right]);
right--;
if (top <= bottom) {
for (let c = right; c >= left; c--) result.push(matrix[bottom][c]);
bottom--;
}
if (left <= right) {
for (let r = bottom; r >= top; r--) result.push(matrix[r][left]);
left--;
}
}
return result;
}Tradeoff: O(1) extra space. Boundaries do all the work — no visited matrix.
Snowflake-specific tips
Snowflake interviewers want the boundary approach with the two if-guards for the bottom and left rows. Bonus signal: connect to 2D windowing — how would you traverse a 2D-tiled column store in row-major then column-major? The boundary tracking is the same pattern.
Common mistakes
- Forgetting the top <= bottom guard before the bottom row — emits duplicates on single-row matrices.
- Forgetting the left <= right guard before the left column — emits duplicates on single-column matrices.
- Off-by-one when shrinking boundaries (decrementing before the loop runs).
Follow-up questions
An interviewer at Snowflake may pivot to one of these next:
- Spiral Matrix II (LC 59) — generate, not traverse.
- Walk in a snake/zigzag pattern.
- How does Snowflake traverse 2D column tiles?
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why the bottom/left guards?
After top++ and right--, top might exceed bottom (single row exhausted) or right might exceed left. The guards prevent re-emitting already-visited cells.
Why not use a visited matrix?
It works but uses O(mn) extra space. Boundaries achieve O(1) extra space — important if the matrix is huge.
Practice these live with InterviewChamp.AI
Drill Spiral Matrix and other Snowflake interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →