48. 旋转图像

48. 旋转图像

[此处请插入:矩阵顺时针旋转 90 度示意图 / 算法过程演示图]

✨核心逻辑

本题要求 原地 将矩阵顺时针旋转 90 度。这里采用极其经典的 “两遍扫描法”(数学变换法):

  1. 数学推导:对于矩阵中的任意坐标 (i, j),其顺时针旋转 90 度后的新位置为 (j, n - 1 - i)。我们可以将这个过程拆分成两次简单的操作。
  2. 第一步:主对角线翻转(转置)。将矩阵沿左上到右下的对角线进行交换,即交换 matrix[i][j]matrix[j][i]。这一步使得元素的行列坐标互换。
  3. 第二步:水平镜像翻转。对转置后的矩阵,将每一行(即横向)进行左右镜像翻转。结合第一步,刚好等同于完成了顺时针旋转 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左半部分即可,否则交换两次等于没有交换