力扣hot100-48.旋转图像-转置翻转详解

LeetCode 48. 旋转图像:转置 + 翻转详解

1. 这道题属于什么算法思想

这题主要归类为:

text 复制代码
矩阵 / 原地变换 / 坐标映射

它不是动态规划、贪心或回溯题。

题目要求在原矩阵上完成顺时针旋转 90 度,不能创建另一个同样大小的矩阵。

最推荐的原地做法是:

text 复制代码
1. 沿主对角线转置矩阵。
2. 翻转每一行。

这两步组合起来,刚好得到顺时针旋转 90 度的结果。

2. 这道题到底在问什么

例如:

text 复制代码
matrix =
[
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]

顺时针旋转 90 度后,应变成:

text 复制代码
[
  [7, 4, 1],
  [8, 5, 2],
  [9, 6, 3]
]

题目要求:

text 复制代码
直接修改 matrix。
不能创建另一个 n x n 的结果矩阵。

3. 顺时针旋转的坐标规律

设矩阵大小为:

text 复制代码
n x n

原位置:

text 复制代码
(i, j)

顺时针旋转 90 度后的位置是:

text 复制代码
(j, n - 1 - i)

例如在 3 x 3 矩阵中:

text 复制代码
matrix[2][0] = 7

旋转后去:

text 复制代码
matrix[0][0]

代入公式:

text 复制代码
(2, 0) -> (0, 3 - 1 - 2) -> (0, 0)

再例如:

text 复制代码
matrix[0][0] = 1

旋转后去:

text 复制代码
matrix[0][2]

代入公式:

text 复制代码
(0, 0) -> (0, 3 - 1 - 0) -> (0, 2)

如果允许额外矩阵,可以直接根据这个映射写:

java 复制代码
result[j][n - 1 - i] = matrix[i][j];

但这样需要 O(n^2) 额外空间,不满足题目原地要求。

4. 为什么不能直接在原矩阵按坐标赋值

假设直接写:

java 复制代码
matrix[j][n - 1 - i] = matrix[i][j];

会覆盖掉仍然需要使用的旧值。

例如最开始把:

text 复制代码
matrix[0][0] = 1

写到:

text 复制代码
matrix[0][2]

原来的:

text 复制代码
matrix[0][2] = 3

就丢失了,之后无法再把 3 移到它正确的位置。

因此必须通过交换,或者把整个变换拆成不会破坏信息的原地操作。

5. 把旋转拆成转置和每行翻转

第一步:沿主对角线转置

主对角线是:

text 复制代码
左上 -> 右下

转置的规则是:

text 复制代码
matrix[i][j] 和 matrix[j][i] 交换。

它的效果是行、列互换。

原矩阵:

text 复制代码
1 2 3
4 5 6
7 8 9

转置后:

text 复制代码
1 4 7
2 5 8
3 6 9

第二步:翻转每一行

对转置后的每一行进行左右翻转:

text 复制代码
1 4 7  ->  7 4 1
2 5 8  ->  8 5 2
3 6 9  ->  9 6 3

最终:

text 复制代码
7 4 1
8 5 2
9 6 3

这正是原矩阵顺时针旋转 90 度后的结果。

因此:

text 复制代码
顺时针旋转 90 度 = 转置 + 翻转每一行。

6. 为什么这两步一定等价于顺时针旋转

从坐标角度看。

原元素的位置是:

text 复制代码
(i, j)

经过转置

转置后位置是:

text 复制代码
(j, i)

再经过每行左右翻转

行号不变,列下标 i 会变成:

text 复制代码
n - 1 - i

最终位置是:

text 复制代码
(j, n - 1 - i)

这和顺时针旋转 90 度的坐标规律完全一致:

text 复制代码
(i, j) -> (j, n - 1 - i)

所以它不是巧合,而是两步坐标变换组合后正好等于目标变换。

7. 转置时为什么只遍历上三角

转置需要交换:

text 复制代码
matrix[i][j] <-> matrix[j][i]

例如:

text 复制代码
matrix[0][1] <-> matrix[1][0]

如果遍历完整矩阵,会发生两次交换:

text 复制代码
处理 (0, 1):交换 2 和 4。
处理 (1, 0):又把 4 和 2 交换回来。

最终等于没交换。

因此只遍历主对角线的上方区域:

java 复制代码
for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
        // 交换 matrix[i][j] 和 matrix[j][i]。
    }
}

j = i + 1 的含义是:

text 复制代码
j == i:主对角线元素,和自己交换没有意义。
j < i:下三角区域,对应交换已经在上三角完成。
j > i:只处理上三角,每对元素恰好交换一次。

8. Java 代码完整注释

java 复制代码
class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;

        // 第一步:沿主对角线转置。
        // 只遍历上三角,避免同一对元素交换两次。
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }

        // 第二步:翻转每一行。
        // 转置后再左右翻转每一行,就得到顺时针旋转 90 度的结果。
        for (int i = 0; i < n; i++) {
            int left = 0;
            int right = n - 1;

            // 双指针交换当前行两端元素,实现左右翻转。
            while (left < right) {
                int temp = matrix[i][left];
                matrix[i][left] = matrix[i][right];
                matrix[i][right] = temp;

                left++;
                right--;
            }
        }
    }
}

9. 用 4 x 4 矩阵验证

原矩阵:

text 复制代码
1  2  3  4
5  6  7  8
9 10 11 12
13 14 15 16

先转置:

text 复制代码
1  5  9 13
2  6 10 14
3  7 11 15
4  8 12 16

再翻转每一行:

text 复制代码
13  9  5 1
14 10  6 2
15 11  7 3
16 12  8 4

这就是原矩阵顺时针旋转 90 度后的结果。

10. 复杂度分析

转置需要交换主对角线上方的元素,数量约为:

text 复制代码
n * (n - 1) / 2

翻转每一行也会处理约:

text 复制代码
n * n / 2

因此时间复杂度是:

text 复制代码
O(n^2)

这是合理且最优的,因为矩阵本身就有 n^2 个元素,至少需要处理它们。

额外空间复杂度是:

text 复制代码
O(1)

只使用了 ntempleftright 等常数个变量,没有创建新矩阵。

11. 总结

这题属于:

text 复制代码
矩阵 / 原地变换 / 坐标映射

顺时针旋转 90 度的坐标规律是:

text 复制代码
(i, j) -> (j, n - 1 - i)

原地实现不直接逐个按坐标赋值,而是把操作拆成:

text 复制代码
先转置: (i, j) -> (j, i)
再翻转每一行:列 i -> n - 1 - i

合起来刚好得到:

text 复制代码
(i, j) -> (j, n - 1 - i)

一句话记忆:

text 复制代码
顺时针旋转 90 度:先沿主对角线转置,再翻转每一行。
相关推荐
满天星83035771 小时前
【算法】最长递增子序列(三种解法)
算法
啦啦啦啦啦zzzz2 小时前
算法:贪心算法
c++·算法·leetcode·贪心算法
清泓y4 小时前
RAG 技术
算法·ai
阿慧今天瘦了嘛4 小时前
计算机组成原理概述:从硬件到软件的桥梁
计算机网络·算法
网站优化(SEO)专家4 小时前
SEO核心算法拆解:网站排名快速提升的武林秘籍!
算法·搜索引擎·网站排名·核心算法
惊讶的猫5 小时前
CLGSI
人工智能·算法·机器学习
ysa0510306 小时前
【板子】二分答案(最大最小?)
c++·笔记·算法·板子
科技之门6 小时前
百公里管网漏损分级定位实战方案2026
前端·人工智能·算法
木木子226 小时前
# 猜数字游戏 — HarmonyOS交互逻辑与随机算法实现
算法·游戏·华为·交互·harmonyos