LeetCode 热题 100 之 48.旋转图像

解题思路

要在原地将图像顺时针旋转 90 度,可以采用两步法:

  1. 矩阵转置 :将矩阵的行和列互换,即 matrix[i][j]matrix[j][i] 交换。
  2. 每行反转:将转置后矩阵的每一行元素进行反转。

代码实现

复制代码
class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;
        
        // 1. 矩阵转置
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
        
        // 2. 反转每一行
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n / 2; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[i][n - 1 - j];
                matrix[i][n - 1 - j] = temp;
            }
        }
    }
}

复杂度分析

  • 时间复杂度:O (n²)。需要遍历矩阵两次(转置和反转),每次遍历的时间复杂度均为 O (n²)。
  • 空间复杂度:O (1)。所有操作均在原矩阵上进行,未使用额外的辅助空间。

示例验证

以示例 1 的输入 [[1,2,3],[4,5,6],[7,8,9]] 为例:

  1. 转置后[[1,4,7],[2,5,8],[3,6,9]]
  2. 反转每行后[[7,4,1],[8,5,2],[9,6,3]],与示例输出一致。

官方题解

1. 代码功能与核心逻辑解读

这段代码的整体功能是:将一个 n x n 的二维矩阵顺时针旋转 90 度,最终结果覆盖原矩阵。

复制代码
class Solution {
    public void rotate(int[][] matrix) {
        // 1. 获取矩阵的边长(n x n矩阵)
        int n = matrix.length;
        // 2. 创建一个和原矩阵大小相同的辅助矩阵,用于暂存旋转后的结果
        int[][] matrix_new = new int[n][n];
        
        // 3. 核心:将原矩阵的元素映射到辅助矩阵的对应位置
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                // 关键映射公式:原矩阵[i][j] → 辅助矩阵[j][n-i-1]
                matrix_new[j][n - i - 1] = matrix[i][j];
            }
        }
        
        // 4. 将辅助矩阵的结果复制回原矩阵(满足题目"修改原矩阵"的要求)
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                matrix[i][j] = matrix_new[i][j];
            }
        }
    }
}
关键映射公式解释

顺时针旋转 90 度的元素位置对应关系:

  • 原矩阵中第 i 行、第 j 列的元素 matrix[i][j]
  • 旋转后会出现在辅助矩阵的第 j 行、第 n-i-1 列(matrix_new[j][n-i-1]

举个例子(以 3x3 矩阵为例):

原位置 旋转后位置 对应公式验证
(0,0) (0,2) j=0, n-i-1=3-0-1=2
(0,2) (2,2) j=2, n-i-1=3-0-1=2
(2,0) (0,0) j=0, n-i-1=3-2-1=0
2. 解法对比(辅助矩阵 vs 原地旋转)
维度 辅助矩阵解法(你提供的代码) 原地旋转解法(之前的代码)
空间复杂度 O (n²)(需要额外 n² 空间) O (1)(无额外空间)
时间复杂度 O (n²)(两次遍历矩阵) O (n²)(两次遍历矩阵)
实现难度 低(逻辑直观,公式易记) 中(需要理解转置 + 反转)
适用场景 允许使用额外空间、追求简洁 要求原地操作、空间敏感
3. 代码优化

如果你想保留 "辅助矩阵" 的思路,可简化复制步骤(Java 中可直接复制数组行):

复制代码
class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;
        int[][] matrix_new = new int[n][n];
        // 1. 映射元素到辅助矩阵
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                matrix_new[j][n - i - 1] = matrix[i][j];
            }
        }
        // 2. 简化复制:直接复制每一行(等价于原代码的双层循环)
        System.arraycopy(matrix_new, 0, matrix, 0, n);
    }
}
总结
  1. 代码核心是位置映射 + 辅助矩阵,逻辑直观,适合新手理解旋转的位置规律;
  2. 该解法的缺点是需要 O(n²) 的额外空间,而原地旋转解法(转置 + 反转)可做到空间复杂度 O(1)
  3. 关键映射公式 matrix_new[j][n-i-1] = matrix[i][j] 是顺时针旋转 90 度的核心,记住这个公式就能快速实现辅助矩阵解法。
相关推荐
Frostnova丶2 小时前
LeetCode 1022. 从根到叶的二进制数之和
算法·leetcode
不会敲代码12 小时前
别再背柯里化面试题了,看完这篇你自己也会写
javascript·算法·面试
snowfoootball2 小时前
优先队列/堆 题目讲解
学习·算法
SamtecChina20232 小时前
Samtec连接器设计研究 | 载流量:温升为什么重要?
大数据·网络·人工智能·算法·计算机外设
程序员南飞2 小时前
排序算法举例
java·开发语言·数据结构·python·算法·排序算法
adore.9682 小时前
2.24 oj95 96 97
开发语言·c++·算法
白中白121382 小时前
算法题-16
算法
梦帮科技2 小时前
【DREAMVFIA开源】量子互联网协议:节点通信与路由算法
人工智能·神经网络·算法·生成对抗网络·开源·量子计算
菜鸡儿齐2 小时前
leetcode-搜索插入位置
数据结构·算法·leetcode