旋转图像
Rotate Image
把 n × n 矩阵原地顺时针旋转 90°,不能另开一个矩阵复制。
在力扣中练习题目描述
给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[[7,4,1],[8,5,2],[9,6,3]]
示例 2:
输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]] 输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
提示:
n == matrix.length == matrix[i].length1 <= n <= 20-1000 <= matrix[i][j] <= 1000
解题思路
转置 + 逐行翻转
先把行列互换,再把每行倒过来
顺时针 90° 后,原来第 c 列会变成第 c 行,而且方向相反。直接按这个关系搬格子会覆盖还没读的值;拆成两步就不会互相踩踏。
第一步转置:只遍历主对角线右上方的 (i,j),与 (j,i) 交换。每个无序点对只处理一次,主对角线不动。
交换 (0,1) 与 (1,0):2 和 5 互换。
只处理 j>i 的上三角,每个无序点对只交换一次。
- i
- 0
- j
- 1
第二步逐行翻转:把每一行左右对调。两步复合,位置 (r,c) 最终到 (c,n-1-r),正是顺时针 90°。
第 0 行 7 5 14 8 → 8 14 5 7。
自拟 4×4 矩阵的值两两不同,任何一次搬错都能从画面上看出来。原地操作只用到几个临时变量,额外空间是 O(1)。
易错点
- 两层循环写成 j 从 0 开始:每对格子会被换回去,等于没转置。
- 先逐行翻转再转置得到的是逆时针 90°,方向反了。
- 转置时只处理 j > i;把主对角线也交换虽然无害,但会多做一半无效操作。
四角轮换 · 逐层原地
把四个角看成一组,循环赋值一次转完一层
同样 O(1) 额外空间,但一次要同时维护四个位置;下标容易写错,适合作为原地操作的进阶对照。
每一层可以看成四个等长的边。位置 (layer,j) 旋转后依次对应右边、下边、左边的三个位置,四次赋值正好闭合,不需要转置。
从左上角开始,先把 matrix[layer][j] 存进临时变量,再按逆时针方向把另外三个位置搬过来,最后把临时变量放到右边。循环只走到 last - 1,四个角由同一层的不同轮次覆盖,不能重复处理。
这种写法少一次全矩阵遍历,但四个下标互相牵扯;面试里写出转置版更稳,四角版更适合检查是否真正理解了下标映射。
- 1layer 从 0 到 n/2-1,圈定当前层。
- 2j 从 layer 走到 last-1,处理这一层的每条边。
- 3按上 → 左 → 下 → 右的顺序搬四个位置。
- 4临时变量补到右上角,进入下一组。
易错点
- j 走到 last:四个角会被重复处理,最后一组互相覆盖。
- 四行赋值的顺序写反会得到逆时针旋转。
- offset 忘记减 layer:内层的下标会整体偏移。
代码与演示
主解法配有图解;对照解法用于比较思路、复杂度或实现方式。
matrix = [[7,2,15,4],[5,12,9,1],[14,6,3,10],[8,13,11,16]]先转置,再把每一行左右翻转;两步合起来正好是顺时针 90°。
查看 C++ 代码
延伸阅读
- 矩阵旋转、转置、镜像都可以拆成两次简单的下标变换,先想清楚复合后的映射再写代码。
- 如果题目允许额外空间,直接按 (r,c) → (c,n-1-r) 写入新矩阵最不容易错。
- 同类题:螺旋矩阵按边界读取,旋转图像按边界写入,关注点都是“一圈一圈”处理。