题目
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
解答
1.模拟前进的走法
假设 当前位置为 (r,c) 初始化位置为(0,0) 初始化向右走 到头后选择一个方向走
方向我们抽象为 两个 数组 正好对应 上下左右走
int[] dr = {0, 1, 0, -1}; //向上 -1 下走 1 不走 0 行走
int[] dc = {1, 0, -1, 0}; //左 -1 右走 1 不走 0 正好对应
然后又一个是否看过flag的数组作为标记, 一旦遇到标记为true 就换到下一个方向
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;
}
}
- 不需要额外的空间 只需要每次改变方向时 将 判断的条件更新
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;
int r0 = 0,r1 = R, c0 = 0, c1 = C;
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 (r0 <= cr && cr < r1 && c0 <= cc && cc < c1 ){
r = cr;
c = cc;
} else {
di = (di + 1) % 4;
r += dr[di];
c += dc[di];
if(dr[di] ==1 ){
r0++;
}
if(dr[di] == -1){
r1--;
}
if(dc[di] == 1){
c0++;
}
if(dc[di] == -1){
c1--;
}
}
}
return ans;
}
}
- 层级法一层 一层的遍历 每层的 顺序 为 → ↓ ←↑
class Solution {
public List < Integer > spiralOrder(int[][] matrix) {
List ans = new ArrayList();
if (matrix.length == 0)
return ans;
int r1 = 0, r2 = matrix.length - 1;
int c1 = 0, c2 = matrix[0].length - 1;
while (r1 <= r2 && c1 <= c2) {
for (int c = c1; c <= c2; c++) ans.add(matrix[r1][c]);
for (int r = r1 + 1; r <= r2; r++) ans.add(matrix[r][c2]);
if (r1 < r2 && c1 < c2) {
for (int c = c2 - 1; c > c1; c--) ans.add(matrix[r2][c]);
for (int r = r2; r > r1; r--) ans.add(matrix[r][c1]);
}
r1++;
r2--;
c1++;
c2--;
}
return ans;
}
}