1. 题目
2. 题解
上当了,和54题不同的是: 增加了 [] 和 [[],[]] 这样的测试,所以需要加上
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return new int[0];
}。
记住: 遇事不决先判空
(1)按圈模拟
class Solution {
int index = 0;
public int[] spiralOrder(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
return new int[0];
int[] res = new int[(matrix[0].length) * (matrix.length)];
circle(matrix, 0, 0, matrix.length - 1, matrix[0].length - 1, res);
return res;
}
// 遍历 以 (x1, y1) 作为左上角,(x2, y2) 作为右下角形成的「圈」
public void circle(int[][] matrix, int x1, int y1, int x2, int y2, int[] res){
if (x2 < x1 || y2 < y1)
return;
// 只有一行时,按「行」遍历, 注意这里要遍历到最后一位 i <= y2, matrix[x1][i]
if(x1 == x2){
for(int i = y1; i <= y2; i++)
res[index++] = matrix[x1][i];
return;
}
// 只有一列时,按「列」遍历,同理 i <= x2, matrix[i][y2]
if(y1 == y2){
for(int i = x1; i <= x2; i++)
res[index++] = matrix[i][y2];
return;
}
// 遍历当前「圈」
for(int i = y1; i < y2; i++)
res[index++] = matrix[x1][i];
for(int i = x1; i < x2; i++)
res[index++] = matrix[i][y2];
for(int i = y2; i > y1; i--)
res[index++] = matrix[x2][i];
for(int i = x2; i > x1; i--)
res[index++] = matrix[i][y1];
// 往里收一圈,继续遍历
circle(matrix, x1 + 1, y1 + 1, x2 - 1, y2 - 1, res);
}
}
(2)模拟矩阵
class Solution {
public int[] spiralOrder(int[][] matrix) {
if(matrix.length == 0)
return new int[0];
//左列,右列,上行,下行
int left = 0;
int right = matrix[0].length - 1;
int up = 0;
int down = matrix.length - 1;
int index = 0;
int[] res = new int[(right + 1) * (down + 1)];
while(true) {
// 左列 -> 右列 :固定行不变,从左走到右,从最上面第一行开始循环,向下走
for(int i = left; i <= right; i++)
res[index++] = matrix[up][i];
if(++up > down)
break;
// 上行 -> 下行:固定列不变,从上走到下,从最右边第一列开始循环,向左走
for(int i = up; i <= down; i++)
res[index++] = matrix[i][right];
if(left > --right)
break;
// 右列 -> 左列 :固定行不变,从右走到左,从最下面第一行开始循环,向上走
for(int i = right; i >= left; i--)
res[index++] = matrix[down][i];
if(up > --down)
break;
// 下行 -> 上行:固定列不变,从下走到上,从最左边第一列开始循环,向右走
for(int i = down; i >= up; i--)
res[index++] = matrix[i][left];
if(++left > right)
break;
}
return res;
}
}
(3)按层模拟
数组越界! 还在排查原因
class Solution {
int index = 0;
public int[] spiralOrder(int[][] matrix) {
if(matrix.length == 0 && matrix[0].length == 0)
return new int[0];
int[] res = new int[(matrix[0].length) * (matrix.length)];
circle(matrix, 0, 0, matrix[0].length - 1, matrix.length - 1, res);
return res;
}
// 遍历 以 (x1, y1) 作为左上角,(x2, y2) 作为右下角形成的「圈」
public void circle(int[][] matrix, int x1, int y1, int x2, int y2, int[] res){
if (x2 < x1 || y2 < y1)
return;
// 只有一行时,按「行」遍历, 注意这里要遍历到最后一位 i <= y2, matrix[x1][i]
if(x1 == x2){
for(int i = y1; i <= y2; i++)
res[index++] = matrix[x1][i];
return;
}
// 只有一列时,按「列」遍历,同理 i <= x2, matrix[i][y2]
if(y1 == y2){
for(int i = x1; i <= x2; i++)
res[index++] = matrix[i][y2];
return;
}
// 遍历当前「圈」
for(int i = y1; i < y2; i++)
res[index++] = matrix[x1][i];
for(int i = x1; i < x2; i++)
res[index++] = matrix[i][y2];
for(int i = y2; i > y1; i--)
res[index++] = matrix[x2][i];
for(int i = x2; i > x1; i--)
res[index++] = matrix[i][y1];
// 往里收一圈,继续遍历
circle(matrix, x1 + 1, y1 + 1, x2 - 1, y2 - 1, res);
}
}