LeetCode 48. 旋转图像,一篇搞懂转置+反转的经典技巧
一、题目描述
给定一个 n × n 的二维矩阵,表示一张图片。
请将图片顺时针旋转 90°。
要求:
- 必须原地修改矩阵
- 不能使用额外矩阵存储结果
示例:
输入:
[
[1,2,3],
[4,5,6],
[7,8,9]
]
输出:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
二、最容易想到的方法
很多人第一反应是:
新建一个矩阵。
new[j][n–1–i] = matrix[i][j]
这样确实能完成旋转。
但题目要求:
必须原地修改
因此额外开二维数组的方法不能作为最终答案。
三、观察旋转后的规律
原矩阵:
1 2 3
4 5 6
7 8 9
顺时针旋转90度:
7 4 1
8 5 2
9 6 3
直接看似乎没规律。
但是如果拆成两步观察:
第一步:矩阵转置
沿主对角线交换元素。
得到:
1 4 7
2 5 8
3 6 9
第二步:每行反转
第一行:
1 4 7
↓
7 4 1
第二行:
2 5 8
↓
8 5 2
第三行:
3 6 9
↓
9 6 3
最终得到:
7 4 1
8 5 2
9 6 3
正好就是答案。
因此:
顺时针旋转90° = 转置 + 每行反转
四、第一步:矩阵转置
转置规则:
matrix[i][j]
⇄
matrix[j][i]
例如:
1 2 3
4 5 6
7 8 9
交换:
matrix[0][1]
⇄
matrix[1][0]
即:
2 ⇄ 4
为什么 j 从 i+1 开始
很多人写:
for i in range(n):
for j in range(n):
这是错误的。
因为:
2 ⇄ 4
交换一次后:
后面又会交换回来。
相当于没换。
因此只遍历对角线上方区域:
for i in range(n):
for j in range(i + 1, n):
这样每组元素只交换一次。
五、第二步:逐行反转
Python最简单:
row.reverse()
例如:
[1,4,7]
变成:
[7,4,1]
所有行处理完成后旋转结束。
六、完整代码
from typing import List
class Solution:
def rotate(self, matrix: List[List[int]]) –> None:
n = len(matrix)
# 转置
for i in range(n):
for j in range(i + 1, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
# 每行反转
for row in matrix:
row.reverse()
七、复杂度分析
时间复杂度:
O(n²)
矩阵所有元素都会访问一次。
空间复杂度:
O(1)
完全原地操作。
八、高频易错点
1、转置区域写错
错误:
for j in range(n)
会导致交换两次。
正确:
for j in range(i + 1, n)
2、把 reverse 当函数用
错误:
row = reverse(row)
正确:
row.reverse()
3、误以为需要返回矩阵
题目要求:
原地修改
因此函数无需 return。
九、一句话总结
顺时针旋转90°本质上不是直接旋转,而是先沿主对角线转置,再将每一行左右翻转,两步组合即可完成原地旋转。


