一、题目描述
给你一个 m
行 n
列的矩阵 matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
二、解题思路
方案一:直接模拟
- 往右开始遍历,特点就是
row
不变,col
加1,一直到超出索引范围或遇到已经遍历的元素。 - 往下遍历,特点是row加1,col不变,一直到超出索引范围或遇到已经遍历的元素。
- 往左遍历,特点是row不变,col减1,一直到超出索引范围或遇到已经遍历的元素。
- 往上遍历,特点是row减1,col不变,一直到超出索引范围或遇到已经遍历的元素。
使用一个2*4的数组来存储方向和行列的变化,2表示行和列的变化,4指四个方向。
方案二:按层模拟
使用四个指针:startRow
,endRow
,startCol
,endCol
,指针初始位置如下,开始遍历:
第一步:第一层的遍历
- 先从
startRow
行开始遍历,从右往左,遍历到从startCol
到endCol
结束; - 然后遍历最后一列,从
startRow+1
行一直到endRow结束 - 再遍历最后一行,从
endCol-1
,一直到startCol+1
结束 - 最后再遍历第一列,从
endRow
到startRow+1
第二步:内层遍历
先将startRow++
,endRow--
,startCol++
,endCol--
,然后再按照第一步的遍历方式继续遍历即可
三、代码演示
方案一:
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
//使用2*4的数组:往右,往下,往左,往上,0表示不变,1是加1,-1是减1
int[][] dirs = {{0,1},{1,0},{0,-1},{-1,0}};
//先得到矩阵的行列长度
int m = matrix.length;;
int n = matrix[0].length;
int row = 0, col = 0;
//使用一个变量来控制方向,默认往右走
int di = 0;
//存放结果
List<Integer> res = new ArrayList<>();
//使用一个boolean来判断某个元素是否被访问
boolean[][] seen = new boolean[m][n];
for (int i=0; i<m*n; i++){
res.add(matrix[row][col]);
seen[row][col] = true; //表示某个元素被访问
//dirs是一个2行4列的数组,dirs[di][0]表示取出dirs中第di行的第1个元素
int nextRow = row + dirs[di][0]; //表示行的变化
int nextCol = col + dirs[di][1]; //表示列的变化
if (nextRow<0 || nextRow>=m || nextCol<0 || nextCol>=n || seen[nextRow][nextCol]){
//改变方向,四个方向,di表示0,1,2,3,dirs的四行
di = (di+1)%4;
}
//更新初始行列
row = row + dirs[di][0];
col = col + dirs[di][1];
}
return res;
}
}
方案二:
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<>();
//先定义四个指针
int startRow = 0, endRow = matrix.length - 1;
int startCol = 0, endCol = matrix[0].length - 1;
while (startRow <= endRow && startCol <= endCol) {
// top 行
for (int col = startCol; col <= endCol; col++){
res.add(matrix[startRow][col]);
}
// right 列
for (int row = startRow + 1; row <= endRow; row++){
res.add(matrix[row][endCol]);
}
//判断边界
if (startRow < endRow && startCol < endCol) {
// bottom 行
for (int col = endCol - 1; col > startCol; col--){
res.add(matrix[endRow][col]);
}
// left 列
for (int row = endRow; row > startRow; row--){
res.add(matrix[row][startCol]);
}
}
startRow++;
endRow--;
startCol++;
endCol--;
}
return res;
}
}