嗯,每日cv
这种模拟的解法的难点我认为是使用二维数组 directions 模拟顺时针的方向。
class Solution {
public int[] spiralOrder(int[][] matrix) {
// 特殊情况,矩阵为空时返回0
if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
return new int[0];
}
// rows 行 cols 列
int rows = matrix.length,cols = matrix[0].length;
// 初始化一个 visited 数组,大小和矩阵相同
boolean[][] visited = new boolean[rows][cols];
// 路径的总长度,当路径等于total时说明为完整路径,返回即可。
int total = rows*cols;
// 返回的路径初始化
int[] order = new int[total];
// 初始位置
int row = 0,col = 0;
// directions 初始方向向右,后面顺时针移动。
/*
[0,1]右 [1,0]下
[0,-1]左 [-1,0]上
*/
int[][] directions = {{0,1},{1,0},{0,-1},{-1,0}};
// 初始方向向右,即行不变,列+1,对应 directions[0][0] = [0,1]
int directionIndex = 0;
for(int i=0;i<total;i++){
// 路径当前位置等于矩阵当前的行列位置
order[i] = matrix[row][col];
// 走过的位置 visited 为true
visited[row][col] = true;
// 计算下一行、列的位置,
int nextRow = row + directions[directionIndex][0],nextCol = col + directions[directionIndex][1];
// 当下一行、列的值小于0或超出矩阵行列或该行列已被访问,说明方向不对;例如行尾时,需要向下走,而不是继续向右。
if(nextRow < 0 || nextRow>=rows || nextCol <0 || nextCol >= cols || visited[nextRow][nextCol]){
// directionIndex 的取值只有 0 1 2 3 分别对应 directions 的4个元素下标,右、下、左、上
// 右下左上 这个是顺时针顺序,右走不通了,接着向下走,下走不通了,接着向左走,左走不通了,接着向上走,上走不通了又向右,如此往复。
directionIndex = (directionIndex + 1) % 4;
}
// 给行列加上方向值。
row = row + directions[directionIndex][0];
col = col + directions[directionIndex][1];
}
return order;
}
}
同样类似的题目还有54.螺旋矩阵,返回值使用队列返回。
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
// 特殊情况,矩阵为空时返回0
if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
return new ArrayList<Integer>();
}
// rows 行 cols 列
int rows = matrix.length,cols = matrix[0].length;
// 初始化一个 visited 数组,大小和矩阵相同
boolean[][] visited = new boolean[rows][cols];
// 路径的总长度,当路径等于total时说明为完整路径,返回即可。
int total = rows*cols;
// 返回的路径初始化
List<Integer> order = new ArrayList<Integer>();
// 初始位置
int row = 0,col = 0;
// directions 初始方向向右,后面顺时针移动。
/*
[0,1]右 [1,0]下
[0,-1]左 [-1,0]上
*/
int[][] directions = {{0,1},{1,0},{0,-1},{-1,0}};
// 初始方向向右,即行不变,列+1,对应 directions[0][0] = [0,1]
int directionIndex = 0;
for(int i=0;i<total;i++){
// 路径当前位置等于矩阵当前的行列位置
order.add(matrix[row][col]);
// 走过的位置 visited 为true
visited[row][col] = true;
// 计算下一行、列的位置,
int nextRow = row + directions[directionIndex][0],nextCol = col + directions[directionIndex][1];
// 当下一行、列的值小于0或超出矩阵行列或该行列已被访问,说明方向不对;例如行尾时,需要向下走,而不是继续向右。
if(nextRow < 0 || nextRow>=rows || nextCol <0 || nextCol >= cols || visited[nextRow][nextCol]){
// directionIndex 的取值只有 0 1 2 3 分别对应 directions 的4个元素下标,右、下、左、上
// 右下左上 这个是顺时针顺序,右走不通了,接着向下走,下走不通了,接着向左走,左走不通了,接着向上走,上走不通了又向右,如此往复。
directionIndex = (directionIndex + 1) % 4;
}
// 给行列加上方向值。
row = row + directions[directionIndex][0];
col = col + directions[directionIndex][1];
}
return order;
}
}