Spiral Matrix
Traversing a Matrix in Spiral Order
Traversing a matrix in spiral order is a common problem in programming, where the goal is to extract all elements of a matrix following a specific pattern.
The traversal begins at the top-left corner and proceeds in a clockwise spiral until all elements are covered.
Problem Statement
You are given a rectangular matrix of integers with dimensions m×nm \times nm×n. The task is to return a list containing all the elements of the matrix arranged in spiral order.
This means traversing the matrix in a clockwise spiral pattern, starting from the top-left corner.
Constraints:
- 1 <= matrix.length, matrix[i].length <= 10
- -100 <= matrix[i][j] <= 100
Example 1
Input: matrix = [[1,2],[3,4]]
Output: [1,2,4,3]
Example 2
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [1,2,3,6,9,8,7,4,5]
Example 3
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]
There are mainly 3 approach to solve this problem –
- Recursion
- Iteration
- Iteration (Optimal)
1. Recursion
- Time complexity: O(m∗n)O(m∗n)
- Space complexity: O(min(m,n))
Where m is the number of rows and n is the number of columns.
Python
C++
Java
JavaScript
Python
class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: m, n = len(matrix), len(matrix[0]) res = [] # append all the elements in the given direction def dfs(row, col, r, c, dr, dc): if row == 0 or col == 0: return for i in range(col): r += dr c += dc res.append(matrix[r][c]) # sub-problem dfs(col, row - 1, r, c, dc, -dr) # start by going to the right dfs(m, n, 0, -1, 0, 1) return res
C++
class Solution { public: vectorspiralOrder(vector >& matrix) { int m = matrix.size(), n = matrix[0].size(); vector res; // append all the elements in the given direction dfs(m, n, 0, -1, 0, 1, matrix, res); return res; } void dfs(int row, int col, int r, int c, int dr, int dc, vector >& matrix, vector & res) { if (row == 0 || col == 0) return; for (int i = 0; i < col; i++) { r += dr; c += dc; res.push_back(matrix[r][c]); } // sub-problem dfs(col, row - 1, r, c, dc, -dr, matrix, res); } };
Java
public class Solution { public ListspiralOrder(int[][] matrix) { int m = matrix.length, n = matrix[0].length; List res = new ArrayList<>(); // append all the elements in the given direction dfs(m, n, 0, -1, 0, 1, matrix, res); return res; } private void dfs(int row, int col, int r, int c, int dr, int dc, int[][] matrix, List res) { if (row == 0 || col == 0) return; for (int i = 0; i < col; i++) { r += dr; c += dc; res.add(matrix[r][c]); } // sub-problem dfs(col, row - 1, r, c, dc, -dr, matrix, res); } }
JavaScript
class Solution { /** * @param {number[][]} matrix * @return {number[]} */ spiralOrder(matrix) { const m = matrix.length, n = matrix[0].length; const res = []; // append all the elements in the given direction const dfs = (row, col, r, c, dr, dc) => { if (row === 0 || col === 0) return; for (let i = 0; i < col; i++) { r += dr; c += dc; res.push(matrix[r][c]); } // sub-problem dfs(col, row - 1, r, c, dc, -dr); }; // start by going to the right dfs(m, n, 0, -1, 0, 1); return res; } }
2. Iteration
Time & Space Complexity
- Time complexity: O(m∗n)O(m∗n)
- Space complexity: O(1)O(1)
Where m is the number of rows and n is the number of columns.
Code
C++
Java
Python
JavaScript
C++
class Solution { public: vectorspiralOrder(vector >& matrix) { vector res; int left = 0, right = matrix[0].size(); int top = 0, bottom = matrix.size(); while (left < right && top < bottom) { for (int i = left; i < right; i++) { res.push_back(matrix[top][i]); } top++; for (int i = top; i < bottom; i++) { res.push_back(matrix[i][right - 1]); } right--; if (!(left < right && top < bottom)) { break; } for (int i = right - 1; i >= left; i--) { res.push_back(matrix[bottom - 1][i]); } bottom--; for (int i = bottom - 1; i >= top; i--) { res.push_back(matrix[i][left]); } left++; } return res; } };
Java
public class Solution { public ListspiralOrder(int[][] matrix) { List res = new ArrayList<>(); int left = 0, right = matrix[0].length; int top = 0, bottom = matrix.length; while (left < right && top < bottom) { for (int i = left; i < right; i++) { res.add(matrix[top][i]); } top++; for (int i = top; i < bottom; i++) { res.add(matrix[i][right - 1]); } right--; if (!(left < right && top < bottom)) { break; } for (int i = right - 1; i >= left; i--) { res.add(matrix[bottom - 1][i]); } bottom--; for (int i = bottom - 1; i >= top; i--) { res.add(matrix[i][left]); } left++; } return res; } }
Python
class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: res = [] left, right = 0, len(matrix[0]) top, bottom = 0, len(matrix) while left < right and top < bottom: for i in range(left, right): res.append(matrix[top][i]) top += 1 for i in range(top, bottom): res.append(matrix[i][right - 1]) right -= 1 if not (left < right and top < bottom): break for i in range(right - 1, left - 1, -1): res.append(matrix[bottom - 1][i]) bottom -= 1 for i in range(bottom - 1, top - 1, -1): res.append(matrix[i][left]) left += 1 return res
JavaScript
class Solution { /** * @param {number[][]} matrix * @return {number[]} */ spiralOrder(matrix) { const res = []; let left = 0; let right = matrix[0].length; let top = 0; let bottom = matrix.length; while (left < right && top < bottom) { for (let i = left; i < right; i++) { res.push(matrix[top][i]); } top++; for (let i = top; i < bottom; i++) { res.push(matrix[i][right - 1]); } right--; if (!(left < right && top < bottom)) { break; } for (let i = right - 1; i >= left; i--) { res.push(matrix[bottom - 1][i]); } bottom--; for (let i = bottom - 1; i >= top; i--) { res.push(matrix[i][left]); } left++; } return res; } }
3. Iteration (Optimal)
- Time complexity: O(m∗n)O(m∗n)
- Space complexity: O(1)O(1)
Where m is the number of rows and n is the number of columns.
Code
C++
Java
Python
JavaScript
C++
class Solution { public: vectorspiralOrder(vector >& matrix) { vector res; vector > directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; vector steps = {matrix[0].size(), matrix.size() - 1}; int r = 0, c = -1, d = 0; while (steps[d % 2]) { for (int i = 0; i < steps[d % 2]; i++) { r += directions[d].first; c += directions[d].second; res.push_back(matrix[r][c]); } steps[d % 2]--; d = (d + 1) % 4; } return res; } };
Java
public class Solution { public ListspiralOrder(int[][] matrix) { List res = new ArrayList<>(); int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; int[] steps = {matrix[0].length, matrix.length - 1}; int r = 0, c = -1, d = 0; while (steps[d % 2] > 0) { for (int i = 0; i < steps[d % 2]; i++) { r += directions[d][0]; c += directions[d][1]; res.add(matrix[r][c]); } steps[d % 2]--; d = (d + 1) % 4; } return res; } }
Python
class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: res = [] directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] steps = [len(matrix[0]), len(matrix) - 1] r, c, d = 0, -1, 0 while steps[d & 1]: for i in range(steps[d & 1]): r += directions[d][0] c += directions[d][1] res.append(matrix[r][c]) steps[d & 1] -= 1 d += 1 d %= 4 return res
JavaScript
class Solution { /** * @param {number[][]} matrix * @return {number[]} */ spiralOrder(matrix) { const res = []; const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]; const steps = [matrix[0].length, matrix.length - 1]; let r = 0, c = -1, d = 0; while (steps[d % 2]) { for (let i = 0; i < steps[d % 2]; i++) { r += directions[d][0]; c += directions[d][1]; res.push(matrix[r][c]); } steps[d % 2]--; d = (d + 1) % 4; } return res; } }