Spiral Matrix II
Generate an n-by-n matrix filled 1..n^2 by walking the same four-direction spiral as Spiral Matrix.
5 min read
matrix simulation
Problem#
Given a positive integer n, return an n x n matrix filled with 1 to n^2 in spiral order, starting from the top-left moving right.
Examples#
n = 3→[[1,2,3],[8,9,4],[7,6,5]]n = 1→[[1]]
Constraints#
1 <= n <= 20.
Approach#
Mirror the Spiral Matrix walk: maintain top, bottom, left, right bounds and a running counter. Fill each side, shrink the corresponding bound, repeat.
Solution#
class Solution {public: vector<vector<int>> generateMatrix(int n) { vector<vector<int>> a(n, vector<int>(n, 0)); int top = 0, bottom = n - 1, left = 0, right = n - 1, v = 1; while (top <= bottom && left <= right) { for (int j = left; j <= right; ++j) a[top][j] = v++; ++top; for (int i = top; i <= bottom; ++i) a[i][right] = v++; --right; if (top <= bottom) { for (int j = right; j >= left; --j) a[bottom][j] = v++; --bottom; } if (left <= right) { for (int i = bottom; i >= top; --i) a[i][left] = v++; ++left; } } return a; }};func generateMatrix(n int) [][]int { a := make([][]int, n) for i := range a { a[i] = make([]int, n) } top, bottom, left, right, v := 0, n-1, 0, n-1, 1 for top <= bottom && left <= right { for j := left; j <= right; j++ { a[top][j] = v v++ } top++ for i := top; i <= bottom; i++ { a[i][right] = v v++ } right-- if top <= bottom { for j := right; j >= left; j-- { a[bottom][j] = v v++ } bottom-- } if left <= right { for i := bottom; i >= top; i-- { a[i][left] = v v++ } left++ } } return a}from typing import List
class Solution: def generateMatrix(self, n: int) -> List[List[int]]: a = [[0] * n for _ in range(n)] top, bottom, left, right, v = 0, n - 1, 0, n - 1, 1 while top <= bottom and left <= right: for j in range(left, right + 1): a[top][j] = v v += 1 top += 1 for i in range(top, bottom + 1): a[i][right] = v v += 1 right -= 1 if top <= bottom: for j in range(right, left - 1, -1): a[bottom][j] = v v += 1 bottom -= 1 if left <= right: for i in range(bottom, top - 1, -1): a[i][left] = v v += 1 left += 1 return afunction generateMatrix(n) { const a = Array.from({ length: n }, () => new Array(n).fill(0)); let top = 0, bottom = n - 1, left = 0, right = n - 1, v = 1; while (top <= bottom && left <= right) { for (let j = left; j <= right; j++) a[top][j] = v++; top++; for (let i = top; i <= bottom; i++) a[i][right] = v++; right--; if (top <= bottom) { for (let j = right; j >= left; j--) a[bottom][j] = v++; bottom--; } if (left <= right) { for (let i = bottom; i >= top; i--) a[i][left] = v++; left++; } } return a;}class Solution { public int[][] generateMatrix(int n) { int[][] a = new int[n][n]; int top = 0, bottom = n - 1, left = 0, right = n - 1, v = 1; while (top <= bottom && left <= right) { for (int j = left; j <= right; j++) a[top][j] = v++; top++; for (int i = top; i <= bottom; i++) a[i][right] = v++; right--; if (top <= bottom) { for (int j = right; j >= left; j--) a[bottom][j] = v++; bottom--; } if (left <= right) { for (int i = bottom; i >= top; i--) a[i][left] = v++; left++; } } return a; }}function generateMatrix(n: number): number[][] { const a: number[][] = Array.from({ length: n }, () => new Array(n).fill(0)); let top = 0, bottom = n - 1, left = 0, right = n - 1, v = 1; while (top <= bottom && left <= right) { for (let j = left; j <= right; j++) a[top][j] = v++; top++; for (let i = top; i <= bottom; i++) a[i][right] = v++; right--; if (top <= bottom) { for (let j = right; j >= left; j--) a[bottom][j] = v++; bottom--; } if (left <= right) { for (let i = bottom; i >= top; i--) a[i][left] = v++; left++; } } return a;}Editorial#
For square matrices the bound checks technically aren’t strictly needed in the bottom/left pass when both dimensions shrink in lockstep, but keeping them ensures correctness if n ever becomes 1 (a single cell must be written exactly once).
Complexity#
- Time: O(n^2).
- Space: O(n^2).
Concept revision#
Related#