题目描述
给定一个 n × n
的二维矩阵 matrix
表示一个图像。请你将图像顺时针旋转 90 度。你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
原地算法:在计算机科学中,一个原地算法(in-place algorithm)是一种使用小的,固定数量的额外之空间来转换资料的算法。当算法执行时,输入的资料通常会被要输出的部分覆盖掉。不是原地算法有时候称为非原地(not-in-place)或不得其所(out-of-place)。
示例 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, ], [12, 6, 8, 9], [16, 7, 10, 11]]
提示:
n == matrix.length == matrix[i].length
1 <= n <= 20
-1000 <= matrix[i][j] <= 1000
原地旋转法
核心思路
通过一次旋转四个元素实现原地旋转。对于每个位置 (i, j)
,我们找到旋转后对应的三个位置,使用临时变量完成四个元素的交换。旋转过程如下:
- 左上角元素 → 右上角
- 右上角元素 → 右下角
- 右下角元素 → 左下角
- 左下角元素 → 左上角
旋转公式推导
设矩阵大小为 n
,对于位置 (i, j)
:
- 左上角:
(i, j)
- 右上角:
(j, n-1-i)
- 右下角:
(n-1-i, n-1-j)
- 左下角:
(n-1-j, i)
1 | temp = matrix[i][j] |
遍历范围优化
- 当
n
为偶数时:遍历左上角1/4
区域 - 当
n
为奇数时:遍历左上角1/4 + 中心轴
区域


图形化示例
1 | 初始矩阵: |
代码实现
1 | public void rotate(int[][] matrix) { |
复杂度分析
- 时间复杂度:
O(n²)
,其中n
是matrix
的边长。 - 空间复杂度:
O(1)
,为原地旋转。
翻转组合法
核心思路
通过两次翻转操作实现旋转:
- 水平翻转(上下翻转):
matrix[i][j] ↔ matrix[n-1-i][j]
- 以水平中线为轴交换元素
- 行索引变换:
i → n-1-i
- 列索引不变
- 主对角线翻转(转置):
matrix[i][j] ↔ matrix[j][i]
- 沿主对角线(左上到右下)交换元素
- 行列索引互换:
(i, j) → (j, i)
- 只需遍历对角线一侧避免重复
推导步骤
- 水平翻转后:
(i, j) → (n-1-i, j)
- 主对角线翻转后:
(n-1-i, j) → (j, n-1-i)
- 与顺时针旋转 90° 的坐标变换一致:
(i, j) → (j, n-1-i)
图形化示例
1 | 初始矩阵: |
代码实现
1 | public void rotate(int[][] matrix) { |
复杂度分析
- 时间复杂度:
O(n²)
,其中n
是matrix
的边长。 - 空间复杂度:
O(1)
,为原地旋转。
总结
解法 | 时间复杂度 | 空间复杂度 | 优势 |
---|---|---|---|
原地旋转法 | O(n²) | O(1) | 通过数学推导直接定位旋转位置,单次循环完成操作 |
翻转组合法 | O(n²) | O(1) | 利用基础操作组合实现旋转,逻辑清晰易理解 |
两种方法都满足原地旋转的要求,在实际应用中可根据具体场景选择。翻转组合法更易于理解和扩展(如逆时针旋转只需调整翻转顺序),而原地旋转法在理论上减少了一半的交换操作。