旋转图像
给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 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]
]
思路简单:
考察如下矩阵
a[0][0] a[0][1] a[0][2] a[0][3]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]
a[3][0] a[3][1] a[3][2] a[3][3]
将a[0][0]元素相关的元素旋转之后可以得到
a[3][0] a[0][1] a[0][2] a[0][0]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]
a[3][3] a[3][1] a[3][2] a[0][3]
容易发现,元素a[m][n]经过旋转的坐标是a[n][a.length - m - 1];
我们已经发现单个元素旋转的代码,接下来只需要寻找一共有多少组元素需要进行旋转即可。(四个一组)
还是考察上面的矩阵,我们很容易就能发现
a[3][0] a[0][1] a[0][2] a[0][0]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]
a[3][3] a[3][1] a[3][2] a[0][3]
只需要将加粗的元素所在的一组元素进行旋转,就可以旋转整个矩阵。由此,我们可以写出如下代码:
public void rotate(int[][] matrix) {
int last = 0; //last element be replaced
int next = 0; //next element to be replaced
int nextRow = 0;
int nextCol = 0;
for (int row = 0 ; row < matrix.length / 2 ; row ++) {
for (int col = row ; col < matrix.length - 1 - row ; col ++) {
last = matrix[row][col];
for (int i = 0 ; i < 4 ; i ++) {
nextRow = col;
nextCol = matrix.length - row - 1;
next = matrix[nextRow][nextCol];
matrix[nextRow][nextCol] = last;
last = next;
row = nextRow;
col = nextCol;
}
}
}
}
官网上给出的最佳解法:
说实话,官网上的方法非常有创造性。
(别说什么方法上的局限性,再局限性的方法,自己想不到,就是自己菜,没有什么理由解释)
也是被官网又一次成功实现了智商压制
接下来是解题思路,以一个3*3的矩阵为例:
a[0][0] a[0][1] a[0][2]
a[1][0] a[1][1] a[1][2]
a[2][0] a[2][1] a[2][2]
先进行一次转置
a[0][0] a[1][0] a[2][0]
a[0][1] a[1][1] a[2][1]
a[0][2] a[1][2] a[2][2]
再左右对称一下
a[2][0] a[1][0] a[0][0]
a[2][1] a[1][1] a[0][1]
a[2][2] a[1][2] a[0][2]
然后旋转90°就转完了
代码如下:
/**
* This is leetcode standardized answer
* The method use two symmetries to implement the function
* @param matrix
*/
public void rotate0(int[][] matrix) {
if (matrix.length == 1)
return ;
//first symmetry
int temp = 0;
for (int row = 0 ; row < matrix.length ; row ++)
for (int col = row + 1 ; col < matrix.length ; col ++) {
temp = matrix[row][col];
matrix[row][col] = matrix[col][row];
matrix[col][row] = temp;
}
//end loop
//second symmetry
int limit = matrix.length / 2;
int symmetryCol = 0;
for (int row = 0 ; row < matrix.length ; row ++)
for (int col = 0 ; col < limit ; col ++) {
symmetryCol = matrix.length - 1 - col;
temp = matrix[row][col];
matrix[row][col] = matrix[row][symmetryCol];
matrix[row][symmetryCol] = temp;
}
}