Matrices
Spiral Matrix
DESCRIPTION (inspired by Leetcode.com)
Write a function to traverse an m x n matrix in spiral order and return all elements in a single list. The traversal should start from the top left corner and proceed clockwise, spiraling inward until every element has been visited.
Input:
matrix = [ [0,1,2], [3,4,5], [6,7,8] ]
Output:
[0,1,2,5,8,7,6,3,4]
Explanation: The elements of the matrix are returned in the order they are visited in a clockwise spiral starting from the top left corner.
public class Solution {
public List<Integer> spiral_order(int[][] matrix) {
// Your code goes here
}
}Run your code to see results here
Have suggestions or found something wrong?
Explanation
This solution uses 4 steps to traverse the matrix in spiral order:
1. Top Row
The first step is to pop the first row of the matrix, while copying those elements into the result array from left to right.
public List<Integer> spiralOrder(List<List<Integer>> matrix) {List<Integer> result = new ArrayList<>();while (!matrix.isEmpty()) {result.addAll(matrix.remove(0));if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (List<Integer> row : matrix) {result.add(row.remove(row.size() - 1));}}if (!matrix.isEmpty()) {List<Integer> lastRow = matrix.remove(matrix.size() - 1);Collections.reverse(lastRow);result.addAll(lastRow);}if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (int i = matrix.size() - 1; i >= 0; i--) {result.add(matrix.get(i).remove(0));}}}return result;}
initialize result
0 / 1
2. Right Column
Next, we traverse the right column of the matrix, popping the last element of each remaining row in matrix and copying those elements into the result array from top to bottom.
public List<Integer> spiralOrder(List<List<Integer>> matrix) {List<Integer> result = new ArrayList<>();while (!matrix.isEmpty()) {result.addAll(matrix.remove(0));if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (List<Integer> row : matrix) {result.add(row.remove(row.size() - 1));}}if (!matrix.isEmpty()) {List<Integer> lastRow = matrix.remove(matrix.size() - 1);Collections.reverse(lastRow);result.addAll(lastRow);}if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (int i = matrix.size() - 1; i >= 0; i--) {result.add(matrix.get(i).remove(0));}}}return result;}
traverse top row
0 / 2
3. Bottom Row
Next, we traverse the bottom row of the matrix, popping the last row of matrix and copying those elements into the result array from right to left.
public List<Integer> spiralOrder(List<List<Integer>> matrix) {List<Integer> result = new ArrayList<>();while (!matrix.isEmpty()) {result.addAll(matrix.remove(0));if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (List<Integer> row : matrix) {result.add(row.remove(row.size() - 1));}}if (!matrix.isEmpty()) {List<Integer> lastRow = matrix.remove(matrix.size() - 1);Collections.reverse(lastRow);result.addAll(lastRow);}if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (int i = matrix.size() - 1; i >= 0; i--) {result.add(matrix.get(i).remove(0));}}}return result;}
traverse right column
0 / 1
4. Left Column
Finally, we traverse the left column of the matrix, popping the first element of each remaining row in matrix and copying those elements into the result array from bottom to top.
public List<Integer> spiralOrder(List<List<Integer>> matrix) {List<Integer> result = new ArrayList<>();while (!matrix.isEmpty()) {result.addAll(matrix.remove(0));if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (List<Integer> row : matrix) {result.add(row.remove(row.size() - 1));}}if (!matrix.isEmpty()) {List<Integer> lastRow = matrix.remove(matrix.size() - 1);Collections.reverse(lastRow);result.addAll(lastRow);}if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (int i = matrix.size() - 1; i >= 0; i--) {result.add(matrix.get(i).remove(0));}}}return result;}
traverse bottom row
0 / 1
Repeat
At this point, we have traversed the perimeter of the original matrix in a clockwise spiral order. We repeat the process for the inner submatrix, until there are no more elements left to traverse.
public List<Integer> spiralOrder(List<List<Integer>> matrix) {List<Integer> result = new ArrayList<>();while (!matrix.isEmpty()) {result.addAll(matrix.remove(0));if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (List<Integer> row : matrix) {result.add(row.remove(row.size() - 1));}}if (!matrix.isEmpty()) {List<Integer> lastRow = matrix.remove(matrix.size() - 1);Collections.reverse(lastRow);result.addAll(lastRow);}if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (int i = matrix.size() - 1; i >= 0; i--) {result.add(matrix.get(i).remove(0));}}}return result;}
traverse left column
0 / 2
Solution
public List<Integer> spiralOrder(List<List<Integer>> matrix) {List<Integer> result = new ArrayList<>();while (!matrix.isEmpty()) {result.addAll(matrix.remove(0));if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (List<Integer> row : matrix) {result.add(row.remove(row.size() - 1));}}if (!matrix.isEmpty()) {List<Integer> lastRow = matrix.remove(matrix.size() - 1);Collections.reverse(lastRow);result.addAll(lastRow);}if (!matrix.isEmpty() && !matrix.get(0).isEmpty()) {for (int i = matrix.size() - 1; i >= 0; i--) {result.add(matrix.get(i).remove(0));}}}return result;}
spiral matrix
0 / 8
What is the time complexity of this solution?
O(m * n)
O(N + Q)
O(n log n)
O(log n)