给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 1:

img
img
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

img
img
输入: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].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

思路

我们首先按照标准的坐标系列出上述的例子,向右为轴正向,向上为轴正向。可见,题目的要求是将矩阵沿中心逆时针旋转

[7,8,9]			[9,6,3]
[4,5,6] ==> [8,5,2]
[1,2,3] [7,4,1]

我们以为原点建立坐标系,不难发现,绕矩阵中心逆时针旋转的过程即先将矩阵绕原点旋转,再向右平移个单位长度。

根据线性代数的知识可知,绕原点旋转的过程是一个线性变换,我们不难求出最终的坐标变换公式:

class Solution {

public int[][] m;

public int len;

public void rotate(int[][] matrix) {
// 等价于绕原点逆时针旋转90度 + 平移length - 1
this.m = matrix;
len = matrix.length;
// i表示迭代的长度
for (int i = len, x = 0, y = 0; i > 1; i -= 2) {
for (int j = 0; j < i - 1; j++) {
movePoint(x, y+j);
}
x++; y++;
}
}


public void movePoint(int x, int y) {
// 原始坐标(x, y) 注意y是列 x是行
int value = m[x][y];
for (int i = 0; i < 4; i++) {
int newX = y, newY = len - 1 - x;
// 保存下一个位置的值
int tmp = m[newX][newY];
// 将下一个位置的值覆盖调
m[newX][newY] = value;
// 更新value
value = tmp;
x = newX; y = newY;
}
}
}

复杂度

  • 时间复杂度:
  • 空间复杂度: