LeetCode热题 100——48. 旋转图像
题目:
54. 螺旋矩阵 - 力扣(LeetCode)
给定一个 n × n 的二维矩阵 matrix
表示一个图像。请你将图像顺时针旋转 90 度。
你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[[7,4,1],[8,5,2],[9,6,3]]
示例 2:
输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]] 输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
算法步骤:
第一步:初始化
-
创建结果列表
ans
-
处理空矩阵的特殊情况
-
获取矩阵维度
m
(行数) 和n
(列数) -
初始化四个边界指针:
-
l
(left):左边界,初始为0 -
r
(right):右边界,初始为n-1 -
t
(top):上边界,初始为0 -
b
(bottom):下边界,初始为m-1
-
第二步:螺旋遍历循环
循环条件:while (l <= r && t <= b)
- 当边界没有重叠时继续
每次循环包含四个阶段:
阶段1:从左到右遍历上边界
for (int i = l; i <= r; i++) {ans.add(matrix[t][i]);
}
t++; // 上边界下移
-
遍历当前最上层的行
-
从最左列到最右列
-
完成后上边界下移一行
阶段2:从上到下遍历右边界
for (int i = t; i <= b; i++) {ans.add(matrix[i][r]);
}
r--; // 右边界左移
-
遍历当前最右层的列
-
从当前顶部到底部
-
完成后右边界左移一列
阶段3:从右到左遍历下边界(需要检查)
if (t <= b) { // 确保还有行需要处理for (int i = r; i >= l; i--) {ans.add(matrix[b][i]);}b--; // 下边界上移
}
-
检查是否还有完整的行
-
从右到左遍历最下层
-
完成后下边界上移一行
阶段4:从下到上遍历左边界(需要检查)
if (l <= r) { // 确保还有列需要处理for (int i = b; i >= t; i--) {ans.add(matrix[i][l]);}l++; // 左边界右移
}
-
检查是否还有完整的列
-
从下到上遍历最左列
-
完成后左边界右移一列
第三步:返回结果
当所有边界重叠时,循环结束,返回结果列表
示例演示
假设矩阵为:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
遍历过程:
-
左→右:1, 2, 3 →
t=1
-
上→下:6, 9 →
r=1
-
右→左:8, 7 →
b=1
-
下→上:4 →
l=1
-
左→右:5 → 结束
代码实现:
class Solution {public List<Integer> spiralOrder(int[][] matrix) {List<Integer> ans = new ArrayList<>(); // 存储遍历结果if (matrix == null || matrix.length == 0) return ans; // 空矩阵处理int m = matrix.length, n = matrix[0].length; // 矩阵的行数和列数int l = 0, r = n - 1, t = 0, b = m - 1; // 定义四个边界:左、右、上、下// 当上下边界和左右边界都没有重叠时继续循环while (l <= r && t <= b) {// 1. 从左到右遍历上边界for (int i = l; i <= r; i++) {ans.add(matrix[t][i]); // 添加当前行从左到右的所有元素}t++; // 上边界下移一行// 2. 从上到下遍历右边界for (int i = t; i <= b; i++) {ans.add(matrix[i][r]); // 添加当前列从上到下的所有元素}r--; // 右边界左移一列// 检查是否还有行需要处理(防止重复遍历)if (t <= b) {// 3. 从右到左遍历下边界for (int i = r; i >= l; i--) {ans.add(matrix[b][i]); // 添加当前行从右到左的所有元素}b--; // 下边界上移一行}// 检查是否还有列需要处理(防止重复遍历)if (l <= r) {// 4. 从下到上遍历左边界for (int i = b; i >= t; i--) {ans.add(matrix[i][l]); // 添加当前列从下到上的所有元素}l++; // 左边界右移一列}}return ans; // 返回螺旋遍历结果}
}