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]
tag:array
method 1
使用一个辅助数组表示某个位置(i,j)是否被访问过,如果下一个位置越界或者是访问过的,那说明该换方向了
public List<Integer> spiralOrder(int[][] matrix) {
boolean right = true, down = false, left = false, up = false;
boolean[][] visit = new boolean[matrix.length][matrix[0].length];
List<Integer> list = new ArrayList<>();
int total = matrix.length * matrix[0].length;
int i = 0, j = 0;
while (true) {
if (total == 0)
break;
if (right) {
if (j == matrix[i].length || visit[i][j]) {
right = false;
down = true;
i++;
j--;
continue;
} else {
list.add(matrix[i][j]);
visit[i][j] = true;
j++;
}
}
if (down) {
if (i == matrix.length || visit[i][j]) {
down = false;
left = true;
i--;
j--;
continue;
} else {
list.add(matrix[i][j]);
visit[i][j] = true;
i++;
}
}
if (left) {
if (j == -1 || visit[i][j]) {
left = false;
up = true;
j++;
i--;
continue;
} else {
list.add(matrix[i][j]);
visit[i][j] = true;
j--;
}
}
if (up) {
if (i == -1 || visit[i][j]) {
up = false;
right = true;
i++;
j++;
continue;
} else {
list.add(matrix[i][j]);
visit[i][j] = true;
i--;
}
}
total--;
}
return list;
}
method 2
上面的方法中,if和else过多过于繁杂,观察题目我们可以发现,遍历的方向是有顺序的,永远是往右,往下,往左,往上。因此,我们可以通过加法+求余来得到下一个方向,因此,也能够知道x,y该加还是该减,还是该不变
dr 表示row上的操作,dc 表示在column上的操作,当往左或往右时,行数不变,因此dr[0]/dr[2]都为0
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List ans = new ArrayList();
if (matrix.length == 0) return ans;
int R = matrix.length, C = matrix[0].length;
boolean[][] seen = new boolean[R][C];
int[] dr = {0, 1, 0, -1};
int[] dc = {1, 0, -1, 0};
int r = 0, c = 0, di = 0;
for (int i = 0; i < R * C; i++) {
ans.add(matrix[r][c]);
seen[r][c] = true;
int cr = r + dr[di];
int cc = c + dc[di];
if (0 <= cr && cr < R && 0 <= cc && cc < C && !seen[cr][cc]){
r = cr;
c = cc;
} else {
di = (di + 1) % 4;
r += dr[di];
c += dc[di];
}
}
return ans;
}
}
summary:
- 如果题目的方向是有规律的,是有循环的,那么可以使用加法和求余来控制方向!