文章目录
前言
本专栏文章为《LeetCode 热题 100》的刷题题解,相关内容如有侵权,立即删除。
一、题目
1、原题链接
2、题目描述
二、个人思路整理
1、思路分析
思路1:几何翻转
将顺时针旋转 90° 拆解为两次对称翻转:
- 上下翻转(水平中轴线翻转):将第 i i i 行与第 n − 1 − i n - 1 - i n−1−i 行整体交换。 matrix i j ⟷ matrix n − 1 − i j \text{matrix}ij \longleftrightarrow \text{matrix}n - 1 - ij matrixij⟷matrixn−1−ij
- 沿主对角线转置:交换第 i i i 行第 j j j 列与第 j j j 行第 i i i 列(注意只遍历上三角或下三角)。 matrix i j ⟷ matrix j i \text{matrix}ij \longleftrightarrow \text{matrix}ji matrixij⟷matrixji也可以先转置再左右翻转(每行内部 reverse),效果完全一致。
思路2:四位置循环轮换(分圈旋转)
矩阵旋转本质上是 4 个对应位置的元素依次轮换: 左上 → 右上 → 右下 → 左下 → 左上 \text{左上} \to \text{右上} \to \text{右下} \to \text{左下} \to \text{左上} 左上→右上→右下→左下→左上
顺时针旋转 90° 的基本移动规律是: 原位置 ( r , c ) ⟶ 目标位置 ( c , n − 1 − r ) \text{原位置 }(r, c) \longrightarrow \text{目标位置 }(c, n - 1 - r) 原位置 (r,c)⟶目标位置 (c,n−1−r)
顺着这个映射关系连续推导 4 步,具体坐标对应关系:
- 点 1(左上角区域): ( i , j ) (i, j) (i,j) 移到 ( j , n − 1 − i ) (j, n - 1 - i) (j,n−1−i)
- 点 2(右上角区域): ( j , n − 1 − i ) (j, n - 1 - i) (j,n−1−i) 移到 ( n − 1 − i , n − 1 − j ) (n - 1 - i, n - 1 - j) (n−1−i,n−1−j)
- 点 3(右下角区域): ( n − 1 − i , n − 1 − j ) (n - 1 - i, n - 1 - j) (n−1−i,n−1−j) 移到 ( n − 1 − j , i ) (n - 1 - j, i) (n−1−j,i)
- 点 4(左下角区域): ( n − 1 − j , i ) (n - 1 - j, i) (n−1−j,i) 移回 ( i , j ) (i, j) (i,j)
只需要用一个临时变量暂存其中一个值,按逆时针方向逐个覆盖即可。遍历范围只需覆盖矩阵的 左上角四分之一区域:
- 行遍历:
i从0到n / 2 - 1 - 列遍历:
j从0到(n + 1) / 2 - 1
2、解题代码
思路1:几何翻转
cpp
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
// 1. 上下翻转
for (int i = 0; i < n / 2; i++) {
swap(matrix[i], matrix[n - 1 - i]);
}
// 2. 主对角线翻转(转置)
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
swap(matrix[i][j], matrix[j][i]);
}
}
}
};
复杂度分析
- 时间复杂度: O ( n 2 ) O(n^2) O(n2),矩阵中每个元素访问常数次。
- 空间复杂度: O ( 1 ) O(1) O(1),仅使用常数级额外空间,严格满足原地旋转要求。
思路2:四位置循环轮换(分圈旋转)
cpp
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
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;
}
}
}
};
复杂度分析
- 时间复杂度: O ( n 2 ) O(n^2) O(n2),矩阵中每个元素访问常数次。
- 空间复杂度: O ( 1 ) O(1) O(1),仅使用常数级额外空间,严格满足原地旋转要求。
三、知识风暴
原地矩阵变换 是「旋转图像」这类矩阵操作题的核心思想:在不借助额外矩阵的前提下,通过坐标映射与元素交换,直接对原矩阵进行变换。由于题目要求 O ( 1 ) O(1) O(1) 额外空间,这类题通常采用「对称翻转」或「循环轮换」的方式,避免开辟新的二维数组。
算法核心思想:
- 坐标映射 :旋转 90° 的本质是建立原坐标 ( r , c ) (r, c) (r,c) 到目标坐标 ( c , n − 1 − r ) (c, n - 1 - r) (c,n−1−r) 的一一映射,所有解法都围绕这一映射展开。
- 对称翻转组合:将旋转拆解为「上下翻转 + 主对角线转置」两次对称操作,每次操作都是简单的两两交换,代码直观且不易出错。
- 四位置循环轮换:利用坐标映射连续推导 4 步,让 4 个对应位置的元素依次轮换,只需一个临时变量即可完成,遍历范围仅覆盖左上角四分之一区域。
- 空间压缩 :整个过程只使用常数个临时变量,不额外开辟与矩阵规模相关的存储,空间复杂度为 O ( 1 ) O(1) O(1)。
算法变体与扩展:
- 逆时针旋转 90° :只需调整坐标映射为 ( r , c ) → ( n − 1 − c , r ) (r, c) \to (n - 1 - c, r) (r,c)→(n−1−c,r),或等价地改为「左右翻转 + 主对角线转置」,思路完全对称。
- 旋转 180° :等价于「上下翻转 + 左右翻转」,或直接交换 ( i , j ) (i, j) (i,j) 与 ( n − 1 − i , n − 1 − j ) (n - 1 - i, n - 1 - j) (n−1−i,n−1−j),无需转置。
- 旋转 270°(即逆时针 90°):可拆解为「左右翻转 + 主对角线转置」,或直接复用逆时针映射。
- 非方阵处理 :对于 m × n m \times n m×n 的矩形矩阵,旋转后尺寸变为 n × m n \times m n×m,无法原地完成,必须借助额外矩阵,此时应改用「逐层拷贝」的思路。
与其他算法的对比:
- 几何翻转法 : O ( n 2 ) O(n^2) O(n2) 时间、 O ( 1 ) O(1) O(1) 空间,通过两次对称翻转组合实现旋转,代码最简洁,是本题最易理解的解法。
- 四位置循环轮换法 : O ( n 2 ) O(n^2) O(n2) 时间、 O ( 1 ) O(1) O(1) 空间,直接按坐标映射逐个轮换元素,只需一个临时变量,是本题最优解。
- 辅助矩阵法 : O ( n 2 ) O(n^2) O(n2) 时间、 O ( n 2 ) O(n^2) O(n2) 空间,直接按映射关系填入新矩阵,思路最简单但空间开销大,不满足本题 O ( 1 ) O(1) O(1) 额外空间要求。
相关 LeetCode 例题:
- 48. 旋转图像(本题,原地矩阵旋转)
- 54. 螺旋矩阵(矩阵遍历,边界收缩法)
- 59. 螺旋矩阵 II(按螺旋顺序填充矩阵,思路对称)
- 73. 矩阵置零(矩阵遍历与原地标记)

