48. 旋转图像
[此处请插入:矩阵顺时针旋转 90 度示意图 / 算法过程演示图]
✨核心逻辑
本题要求 原地 将矩阵顺时针旋转 90 度。这里采用极其经典的 “两遍扫描法”(数学变换法):
- 数学推导:对于矩阵中的任意坐标
(i, j),其顺时针旋转 90 度后的新位置为(j, n - 1 - i)。我们可以将这个过程拆分成两次简单的操作。 - 第一步:主对角线翻转(转置)。将矩阵沿左上到右下的对角线进行交换,即交换
matrix[i][j]和matrix[j][i]。这一步使得元素的行列坐标互换。 - 第二步:水平镜像翻转。对转置后的矩阵,将每一行(即横向)进行左右镜像翻转。结合第一步,刚好等同于完成了顺时针旋转 90 度的效果。
🔥代码实现(含详细变量注释)
class Solution {
public void rotate(int[][] matrix) {
// n:记录二维矩阵的边长(行数和列数)
int n = matrix.length;
// 第一步:沿主对角线(左上到右下)进行翻转(即矩阵的转置)
// 外层循环 i:遍历每一行
for (int i = 0; i < n; i++) {
// 内层循环 j:从 i 开始遍历每一列(避免重复交换已经交换过的元素,从而原地完成转置)
for (int j = i; j < n; j++) {
// temp:用于交换两个元素的临时中转变量
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
// 第二步:对矩阵的每一行进行水平镜像翻转(左右交换)
// 外层循环 i:遍历每一行
for (int i = 0; i < n; i++) {
// 内层循环 j:遍历当前行的前半部分(只需要遍历到 n/2 即可完成整行的左右交换)
for (int j = 0; j < n / 2; j++) {
// temp:用于交换两个元素的临时中转变量
int temp = matrix[i][j];
// 将右侧对称位置的元素覆盖到左侧当前位置
matrix[i][j] = matrix[i][n - 1 - j];
// 将暂存的左侧元素赋值给右侧对称位置,完成整行镜像交换
matrix[i][n - 1 - j] = temp;
}
}
}
}
- ⏱️复杂度分析
时间复杂度:O(N^2),其中 N 是矩阵的边长。我们需要遍历矩阵中所有的元素进行转置交换(约 N^2 / 2 次操作),以及每一行的一半进行水平翻转(约 N^2 / 2 次操作),总操作次数与矩阵元素总数成正比。
空间复杂度:O(1),使用了常数个额外的整型变量 n、i、j 以及交换时使用的临时变量 temp,没有申请额外的二维数组空间,满足题目原地操作的要求。
🔍总结一下:
注意事项 : 就是第一个行列交换的时候内层循环从i
开始,防止重复交换。第二个循环也是,只用交换n d左半部分即可,否则交换两次等于没有交换