LeetCode 48中等矩阵 · 原地旋转
旋转图像 图解题解
这道题到底在问什么
把 n×n 矩阵顺时针旋转 90 度,要求原地修改。
- matrix
- [[1,2,3],[4,5,6],[7,8,9]]
- 输出
- [[7,4,1],[8,5,2],[9,6,3]]
最优解:一步一步想明白
- 3关键不是背模板,而是看懂为什么这题适合矩阵 · 原地旋转。
- 4顺时针旋转 90° = 沿主对角线转置 + 每行左右反转。原矩阵 [[1,2,3],[4,5,6],[7,8,9]]。
- 5第一步转置:沿主对角线翻折,matrix[i][j] ↔ matrix[j][i]。对角线 1、5、9(灰)不动,其余成对交换 → [[1,4,7],[2,5,8],[3,6,9]]。
- 6关键帧:第二步把每一行左右反转:[1,4,7]→[7,4,1]、[2,5,8]→[8,5,2]、[3,6,9]→[9,6,3] → 旋转完成。
- 7结果 [[7,4,1],[8,5,2],[9,6,3]]。全程在原矩阵上交换元素,不开新矩阵 → O(1) 额外空间。
- 10把这句话记住,下次遇到同类题,就能更快选出方向。
- 15把这题练到能复述后,再去同类题里迁移:先复用状态定义,再调整边界条件。
⚠️ 容易写错的地方
✗ 错:新建一个矩阵再拷回
✓ 对:原地题用转置加翻转
额外矩阵不符合原地要求
✗ 错:转置时 j 从 0 开始
✓ 对:内层 j 从 i+1 开始
j 从 0 会把每对交换两次、等于没换;只交换上三角。
✗ 错:转置后忘了反转每行
✓ 对:转置 + 每行反转两步缺一不可
只转置是沿对角线镜像,不是旋转;还要左右翻转。
完整代码(Python / C++ / Java)
Python
class Solution:
def rotate(self, matrix):
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()C++
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
swap(matrix[i][j], matrix[j][i]);
for (auto& row : matrix) reverse(row.begin(), row.end());
}
};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 tmp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = tmp;
}
for (int[] row : matrix)
for (int l = 0, r = n - 1; l < r; l++, r--) {
int tmp = row[l]; row[l] = row[r]; row[r] = tmp;
}
}
}套路模板 · 矩阵 · 原地旋转
# 矩阵原地旋转骨架
# 顺时针90° = 转置 + 每行反转
for i in range(n):
for j in range(i+1, n): # 只换上三角
swap(a[i][j], a[j][i]) # 转置
for row in a: row.reverse() # 每行左右反转class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
swap(matrix[i][j], matrix[j][i]);
for (auto& row : matrix) reverse(row.begin(), row.end());
}
};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 tmp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = tmp;
}
for (int[] row : matrix)
for (int l = 0, r = n - 1; l < r; l++, r--) {
int tmp = row[l]; row[l] = row[r]; row[r] = tmp;
}
}
}复杂度
时间复杂度
O(n²)
转置+反转各扫一遍,共约 n² 次交换
空间复杂度
O(1)
原地交换元素,不开新矩阵
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 旋转图像 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
为什么能 O(1) 原地转?+
转置和翻转都在原矩阵上交换元素,不开新矩阵,O(1) 额外空间。
逆时针旋转怎么改?+
转置 + 上下翻转(或先水平翻转再转置),方向相反。
还有别的原地法吗?+
可按「环」一圈四元素轮换,但转置+翻转更好写、不易错。
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。