class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
int[][] dirs = {{0,1}, {1,0}, {0, -1}, {-1, 0}};
if (matrix == null || matrix[0] == null || matrix.length == 0 || matrix[0].length == 0) {
return null;
}
boolean[][] visited = new boolean[matrix.length][matrix[0].length];
int curDirIndex = 0;
int i = 0, j = 0;
List<Integer> result = new ArrayList<>();
while (i >= 0 && i < matrix.length && j >= 0 && j < matrix[0].length && !visited[i][j]) {
result.add(matrix[i][j]);
visited[i][j] = true;
curDirIndex = getNextDirIndex(curDirIndex, i, j, matrix, visited);
i = i + dirs[curDirIndex][0];
j = j + dirs[curDirIndex][1];
}
return result;
}
private int getNextDirIndex(int curDirIndex, int i, int j, int[][] matrix, boolean[][] visited) {
if (curDirIndex == 0 && (j == matrix[0].length - 1 || visited[i][j + 1])) {
return 1;
} else if (curDirIndex == 1 && (i == matrix.length - 1 || visited[i + 1][j])) {
return 2;
} else if (curDirIndex == 2 && (j == 0 || visited[i][j - 1])) {
return 3;
} else if (curDirIndex == 3 && (i == 0 || visited[i - 1][j])) {
return 0;
} else {
return curDirIndex;
}
}
}