力扣hot100:旋转图像(48)(详细图解以及核心思路剖析)

在解决力扣第48题"旋转图像"时,题目要求将一个 n × n 的矩阵原地顺时针旋转90度(即不使用额外空间)。我采用的是一种直接通过交换四个位置元素的方法来实现旋转。这种方法高效且直观,下面详细解释我的思路和代码。

问题分析

给定一个 n × n 的二维矩阵,我们需要将其顺时针旋转90度。旋转后的矩阵需要满足:

  • 矩阵元素的位置变化规律:原始位置 (i, j) 的元素会移动到 (j, n-1-i)
  • 必须在原矩阵上修改,空间复杂度为 O(1)

核心思想:

核心思路:四个元素一组循环交换

观察旋转的规律,我们可以发现矩阵中的四个元素会构成一个循环

  1. 原始位置 (i, j) 移动到 (j, n-1-i)
  2. 位置 (j, n-1-i) 移动到 (n-1-i, n-1-j)
  3. 位置 (n-1-i, n-1-j) 移动到 (n-1-j, i)
  4. 位置 (n-1-j, i) 移动到 (i, j)

这个过程形成了一个闭环,我们可以用一个临时变量 temp 来辅助这四个位置的元素交换:

java 复制代码
temp = matrix[i][j];
matrix[i][j] = matrix[n-1-j][i];
matrix[n-1-j][i] = matrix[n-1-i][n-1-j];
matrix[n-1-i][n-1-j] = matrix[j][n-1-i];
matrix[j][n-1-i] = temp;
遍历范围的设计

如果直接遍历整个矩阵,每个元素会被交换两次(导致恢复原状)。我们需要确保每个元素只被交换一次 。解决方案是只遍历矩阵的左上角区域

  • 行索引 i :从 0n/2(不包括 n/2)。
  • 列索引 j :从 0(n+1)/2(不包括 (n+1)/2)。

为什么列的范围是 (n+1)/2

  • n 是偶数时,遍历左上角的四分之一区域:
    • i 的范围:[0, n/2)
    • j 的范围:[0, n/2)
  • n 是奇数时,中心元素无需旋转,但中心列的上半部分需要处理:
    • 列的范围扩展到 (n+1)/2,确保覆盖中心列左侧的所有列(见下图)。
java 复制代码
示例:n=3(奇数)
需要遍历的位置:(0,0) 和 (0,1)
   (0,0) -> (2,0) -> (2,2) -> (0,2)
   (0,1) -> (1,0) -> (2,1) -> (1,2)
中心点 (1,1) 保持不变。
代码实现
java 复制代码
class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length; // 矩阵尺寸 n x n
        
        // 遍历左上角区域
        for (int i = 0; i < n / 2; i++) {
            for (int j = 0; j < (n + 1) / 2; j++) {
                // 保存左上角元素
                int temp = matrix[i][j];
                // 左下角元素 -> 左上角
                matrix[i][j] = matrix[n - 1 - j][i];
                // 右下角元素 -> 左下角
                matrix[n - 1 - j][i] = matrix[n - 1 - i][n - 1 - j];
                // 右上角元素 -> 右下角
                matrix[n - 1 - i][n - 1 - j] = matrix[j][n - 1 - i];
                // 临时变量(原左上角)-> 右上角
                matrix[j][n - 1 - i] = temp;
            }
        }
    }
}
示例解析

3x3 矩阵为例:

java 复制代码
初始矩阵:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]

第一步 :旋转 (0,0) 所在的组:

  • (0,0)(2,0)(2,2)(0,2)(0,0)
  • 交换后:
java 复制代码
  [7, 2, 1]
  [4, 5, 6]
  [9, 8, 3]

第二步 :旋转 (0,1) 所在的组:

  • (0,1)(1,0)(2,1)(1,2)(0,1)
  • 交换后:
java 复制代码
  [7, 4, 1]
  [8, 5, 2]
  [9, 6, 3]

最终得到顺时针旋转90度的结果。

复杂度分析
  • 时间复杂度O(n²),每个元素被访问一次。
  • 空间复杂度O(1),仅使用常数级额外空间。
总结

通过将矩阵分为四个位置的循环组,并巧妙设计遍历范围(左上角区域),我们在原地完成了矩阵旋转。这种方法避免了额外的空间开销,且逻辑清晰高效。理解位置映射关系 (i, j) → (j, n-1-i) 是解决本题的关键。

相关推荐
橘颂TA20 分钟前
机器人+工业领域=?
算法·机器人
沐浴露z33 分钟前
详解JDK21新特性【虚拟线程】
java·开发语言·jvm
No0d1es1 小时前
电子学会青少年软件编程(C/C++)1级等级考试真题试卷(2025年9月)
java·c语言·c++·青少年编程·电子学会·真题·一级
_OP_CHEN1 小时前
C++进阶:(七)红黑树深度解析与 C++ 实现
开发语言·数据结构·c++·stl·红黑树·红黑树的旋转·红黑树的平衡调整
我是天龙_绍1 小时前
java 比对两对象大小 重写 comparator
后端
IT_陈寒1 小时前
Python 3.12新特性实测:10个让你的代码提速30%的隐藏技巧 🚀
前端·人工智能·后端
BingoGo1 小时前
从零开始打造 Laravel 扩展包:开发、测试到发布完整指南
后端·php
小O的算法实验室1 小时前
2025年TRE SCI1区TOP,随机环境下无人机应急医疗接送与配送的先进混合方法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
9号达人1 小时前
普通公司对账系统的现实困境与解决方案
java·后端·面试