package com.app.main.LeetCode;
import java.util.ArrayList;
import java.util.List;
/**
* 54
*
* medium
*
* https://leetcode.com/problems/spiral-matrix/
*
* Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
*
* Example 1:
*
* Input:
* [
* [ 1, 2, 3 ],
* [ 4, 5, 6 ],
* [ 7, 8, 9 ]
* ]
* Output: [1,2,3,6,9,8,7,4,5]
* Example 2:
*
* Input:
* [
* [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]
* Created with IDEA
* author:Dingsheng Huang
* Date:2019/10/12
* Time:下午12:19
*/
public class SpiralMatrix {
// simulation - time : O(n) , space: O(n)
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>();
if (matrix.length == 0) {
return result;
}
int rLen = matrix.length;
int cLen = matrix[0].length;
// visited record
boolean[][] visited = new boolean[rLen][cLen];
// control direction
int[] rd = {0, 1, 0, -1};
int[] cd = {1, 0, -1, 0};
int r = 0;
int c = 0;
int currDirect = 0;
int cn = rLen * cLen;
while (cn > 0) {
result.add(matrix[r][c]);
visited[r][c] = true;
// find next position
int nextR = r + rd[currDirect];
int nextC = c + cd[currDirect];
// if need to change direction
if (nextR >= 0 && nextR < rLen && nextC >= 0 && nextC < cLen && !visited[nextR][nextC]) {
r = nextR;
c = nextC;
} else {
// change direction
currDirect = (currDirect + 1) % 4;
r += rd[currDirect];
c += cd[currDirect];
}
cn--;
}
return result;
}
// layer by layer , time : O(n) , space : O(1)
public List<Integer> spiralOrder2(int[][] matrix) {
List<Integer> result = new ArrayList<>();
if (matrix.length == 0) {
return result;
}
int rStart = 0;
int rEnd = matrix.length - 1;
int cStart = 0;
int cEnd = matrix[0].length - 1;
while (rStart <= rEnd && cStart <= cEnd) {
// current layer
for (int i = cStart; i <= cEnd; i++) {
result.add(matrix[rStart][i]);
}
for (int i = rStart + 1; i <= rEnd; i++) {
result.add(matrix[i][cEnd]);
}
if (rStart < rEnd && cStart < cEnd) {
for (int i = cEnd - 1; i >= cStart; i--) {
result.add(matrix[rEnd][i]);
}
for (int i = rEnd - 1; i > rStart; i--) {
result.add(matrix[i][cStart]);
}
}
// next layer
rStart++;
cStart++;
rEnd--;
cEnd--;
}
return result;
}
}