欢迎光临
我们一直在努力

LeetCode 48. 旋转图像,一篇搞懂转置+反转的经典技巧

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°本质上不是直接旋转,而是先沿主对角线转置,再将每一行左右翻转,两步组合即可完成原地旋转。

赞(0)
未经允许不得转载:171主机测评 » LeetCode 48. 旋转图像,一篇搞懂转置+反转的经典技巧
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址