问题描述:
给定一个包含 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]
问题分析:
旋转操作必存在方向的转变。对于一个二维数组(矩阵)而言,顺时针旋转只存在四次方向的改变(右下左上)。假设我们的初始方向是向右,当不能继续向右时,我们就要将方向改变为向下(因为是顺时针旋转),当不能继续向下前时,改变方向为向左,以此类推。。。
在这里,说明一下什么情况下我们就不能按照原方向访问元素。当我们找到的下一个坐标越界或者下一个坐标的元素已经被访问过,此时,我们就不能按照原方向访问了。
因此,我们需要一个标志数组,记录矩阵中的每一个元素是否被访问过。
代码实现:
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List ans = new ArrayList();
if(matrix.length == 0) return ans;
int row = matrix.length, col = matrix[0].length;
// 标志数组:true 表示被访问过,false 表示没被访问过
boolean[][] seen = new boolean[row][col];
// 改变方向时,行坐标的变化(下标为0,表示向右,按照右下左上的顺序)
int[] dr = {0, 1, 0, -1};
// 改变方向时,列坐标的变化
int[] dc = {1, 0, -1, 0};
int r = 0, c = 0, dir = 0;
for (int i = 0; i < row * col; i++) {
ans.add(matrix[r][c]);
seen[r][c] = true;
// 寻找下一个坐标
int nextR = r + dr[dir];
int nextC = c + dc[dir];
// 如果下一个坐标可以访问,访问下一个坐标
// 否则,改变方向,继续寻找下一个方向
if (0 <= nextR && nextR < row && 0 <= nextC && nextC < col && !seen[nextR][nextC]){
r = nextR;
c = nextC;
} else {
dir = (dir + 1) % 4;
r += dr[dir];
c += dc[dir];
}
}
return ans;
}
}
来源:CSDN
作者:小熊已上线
链接:https://blog.csdn.net/weixin_44470078/article/details/104797485