class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<>();
if(matrix == null || matrix.length == 0) return res;
int R = matrix.length, C = matrix[0].length;
int[] dr = {0, 1, 0, -1};
int[] dc = {1, 0, -1, 0};
boolean[][] seen = new boolean[R][C];
int r = 0, c = 0, di = 0;
for (int i = 0; i < R*C; i++) {
res.add(matrix[r][c]);
seen[r][c] = true;
int rNext = r + dr[di];
int cNext = c + dc[di];
if (rNext >= 0 && rNext < R && cNext >= 0 && cNext < C && !seen[rNext][cNext]) {
r = rNext;
c = cNext;
} else {
di = (di + 1) % 4;
r += dr[di];
c += dc[di];
}
}
return res;
}
}