螺旋矩阵
题目描述:
给你一个 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]
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
思路分析:
-
初始化边界 :
首先,我们需要定义四个边界变量,分别表示矩阵的上边界(
top
)、下边界(bottom
)、左边界(left
)和右边界(right
)。初始时,这些边界分别设置为矩阵的第一行、最后一行、第一列和最后一列。 -
循环遍历 :
使用一个循环来遍历矩阵的边界。在每次循环中,我们按照顺时针的顺序遍历矩阵的四个边界(上、右、下、左),并将遍历到的元素添加到结果列表中。
-
更新边界 :
在遍历完每个边界后,我们需要根据遍历的方向来更新相应的边界变量。具体来说:
- 遍历完上边界后,上边界下移(
top++
)。 - 遍历完右边界后,右边界左移(
right--
)。 - 遍历完下边界后,下边界上移(
bottom--
)。 - 遍历完左边界后,左边界右移(
left++
)。
- 遍历完上边界后,上边界下移(
-
终止条件 :
循环会一直进行,直到四个边界交叉,即左边界超过右边界(
left > right
)或上边界超过下边界(top > bottom
)。这时,表示矩阵中的所有元素都已经被遍历完毕,可以结束循环。 -
返回结果 :
循环结束后,返回存储了按顺时针螺旋顺序遍历的矩阵元素的结果列表。
注意,在遍历右边界和下边界时,需要添加一个检查来确保内部还有元素需要遍历。这是因为当矩阵的行数或列数为奇数时,遍历完上边界和左边界后,右边界或下边界可能只剩下单独的一行或一列。如果不进行检查,就会在这一行或一列上重复遍历,导致结果错误。
代码实现:
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>(); // 初始化结果列表
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
// 如果矩阵为空或没有行/列,则直接返回空的结果列表
return result;
}
int left = 0, right = matrix[0].length - 1; // 初始化左右边界
int top = 0, bottom = matrix.length - 1; // 初始化上下边界
while (left <= right && top <= bottom) {
// 遍历上边界
for (int i = left; i <= right; i++) {
result.add(matrix[top][i]); // 将上边界的元素添加到结果列表中
}
top++; // 上边界下移
// 遍历右边界
for (int i = top; i <= bottom; i++) {
result.add(matrix[i][right]); // 将右边界的元素添加到结果列表中
}
right--; // 右边界左移
// 检查是否还有内部元素需要遍历(避免在只剩一行或一列时重复遍历)
if (top <= bottom) {
// 遍历下边界
for (int i = right; i >= left; i--) {
result.add(matrix[bottom][i]); // 将下边界的元素添加到结果列表中
}
bottom--; // 下边界上移
}
if (left <= right) {
// 遍历左边界
for (int i = bottom; i >= top; i--) {
result.add(matrix[i][left]); // 将左边界的元素添加到结果列表中
}
left++; // 左边界右移
}
}
return result; // 返回结果列表
}
}