#48
中等
低频
翻转加转置旋转图像
这是一道围绕图展开的高频练习。建议先掌握「翻转加转置」这套写法,再结合下方步骤讲解理解状态维护、边界处理和复杂度取舍。
图
题目分析
这道题表面上是在处理「旋转图像」,但先要想清楚题目到底让你返回什么,以及过程中哪些约束必须一直满足。从题型上看,它主要在考 图 这些能力。先别急着写代码,先把题目要求翻译成人话,明确结果是什么、约束是什么、过程里要持续维护什么。只有先把题目要求翻译成人话,后面的推荐代码才是在实现思路,而不是直接给答案。
接下来怎么看推荐代码: 带着这个理解再看推荐代码时,重点观察这条主线:先把矩阵上下翻转,再沿主对角线转置,就能原地完成顺时针旋转 90 度。
推荐代码
推荐解法:翻转加转置
时间复杂度: O(n^2)
空间复杂度: O(1)
核心思路: 先把矩阵上下翻转,再沿主对角线转置,就能原地完成顺时针旋转 90 度。
class Solution {
public void rotate(int[][] matrix) {
int n = matrix.length;
for (int top = 0, bottom = n - 1; top < bottom; top++, bottom--) {
int[] temp = matrix[top];
matrix[top] = matrix[bottom];
matrix[bottom] = temp;
}
for (int row = 0; row < n; row++) {
for (int col = row + 1; col < n; col++) {
int temp = matrix[row][col];
matrix[row][col] = matrix[col][row];
matrix[col][row] = temp;
}
}
}
}结构化讲解
面试时怎么讲
开场思路
这题我会把旋转拆成两个原地操作:上下翻转,再主对角线转置。
核心过程
- 先交换第一行和最后一行、第二行和倒数第二行。
- 然后沿主对角线交换对称位置。
- 两个操作都在原矩阵内完成,不需要额外数组。
复杂度总结
时间复杂度 O(n^2),空间复杂度 O(1)。
面试补一句:这题的亮点是把看似复杂的旋转拆成两个简单变换。
核心思路
原地旋转矩阵的难点是如何避免借助额外数组。一个非常稳的思路是把旋转拆成两个可原地完成的操作:上下翻转 + 主对角线转置。
步骤讲解
1
先做上下翻转
把第 i 行和第 n-1-i 行整行交换。
为什么这样做:顺时针旋转后,原来的上方元素会先移动到底部对应位置。
对应代码提示:swap(matrix[top][col], matrix[bottom][col]);
2
再做主对角线转置
交换 matrix[i][j] 和 matrix[j][i],只处理上三角区域。
为什么这样做:经过转置后,行列关系就变成了旋转后的样子。
对应代码提示:for (int j = i + 1; j < n; j++) { ... }
易错点
转置时重复交换两次
如果 j 从 0 开始,会把同一对元素换回来。
正确理解:只遍历
j > i 的上三角区域。把左右翻转和上下翻转搞混
不同的翻转方向会对应不同的旋转方向。
正确理解:顺时针 90 度对应“上下翻转 + 主对角线转置”。
复杂度与适用判断
时间复杂度:O(n^2)
空间复杂度:O(1)
比其他方案更好在哪里:比按四元环逐层旋转更容易写对,也更容易讲清楚。
适用判断:矩阵变换能拆成基础翻转和转置时,优先考虑这种组合思路。
额外提醒
- 核心不是硬记结论,而是理解两个变换叠加后为什么等价于旋转。