这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战
leetcode 螺旋矩阵
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
解题可以就根据题目要求,按照 顺时针螺旋顺序 的方式读取矩阵的元素。顺时针螺旋顺序的访问方向为 右-> 下-> 左-> 上-> 右-> 循环的读取,初始从矩阵的左上角[0][0]开始,一直往右读取,直到超出矩阵边界或者这个元素之前已经读取过了,就开始顺时针转换方向。是否超出矩阵边界就判断下一个元素的下标是否越界;要判断元素是否在之前被读取过,我们可以在读取了元素之后将这个元素设置一个值,比如整形最大值Integer.MArow_VALUE,因为题目矩阵中的元素值范围为-100 <= matrirow[i][j] <= 100,那Integer.MArow_VALUE这个值就不可能出现在未读取的元素中,所以当判断下一个元素值与Integer.MArow_VALUE相等了,就说明下一个将要访问的元素是之前读取过的了;如何转换方向呢?首先需要一个变量可以记录当前方向的,有4种方向并且是按右下左上顺序循环的, 那么可以定义directions初始为0,代表方向为右,每次转换方向directions++,然后当前方向就是direction % 4的结果,即:0代表右方向、1代表下方向、2代表左方向、3代表上方向。同时读取下一个元素时需要根据当前方向读取,可以用row、col表示矩阵的二维下标,基于矩阵中的4个方向可以发现,当前为右方向的时候读取下一个元素是行下标+1即row+1,当方向为下的时候读取下一个元素是列下标+1即col+1,当方向为左的时候读取下一个元素是行下标-1即row-1,当方向为上的时候读取下一个元素是列下标-1即col-1。因此要获取下一个元素的下标需要判断当前方向然后给对应的row或者col的值+1或者-1, 或者使用一个二维数组[[0,1],[1,0],[0,-1],[-1,0]],那么row只需加上[direction % 4][0],col只需加上[direction % 4][1]就可以不额外的判断了。最后如果已经读取的元素数量等于矩阵中的元素数量的时候就结束读取,返回最终结果。
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>();
int rows = matrix.length;
int cols = matrix[0].length;
int row = 0;
int col = 0;
int direction = 0;
int[][] nextIndex = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int total = rows * cols;
for (int i = 0; i < total; i++) {
result.add(matrix[row][col]);
matrix[row][col] = Integer.MAX_VALUE;
int nextRow = row + nextIndex[direction % 4][0];
int nextCol = col + nextIndex[direction % 4][1];
if (nextRow < 0 || nextRow >= rows || nextCol < 0 || nextCol >= cols || matrix[nextRow][nextCol] == Integer.MAX_VALUE) {
direction++;
nextRow = row + nextIndex[direction % 4][0];
nextCol = col + nextIndex[direction % 4][1];
}
row = nextRow;
col = nextCol;
}
return result;
}
}