题目及测试用例
package pid048;
/*旋转图像
给定一个 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]
]
*/
public class main {
public static void main(String[] args) {
int[][] testTable1 ={
{1,2,3},
{4,5,6},
{7,8,9}
};
int[][] testTable2 ={
{ 5, 1, 9,11},
{ 2, 4, 8,10},
{13, 3, 6, 7},
{15,14,12,16}
};
test(testTable1);
test(testTable2);
}
private static void test(int[][] ito) {
Solution solution = new Solution();
int length=ito.length;
for(int i=0;i
首先讲一下这题的思路,首先是一个矩阵中的数字在经过顺时针90度之后的位置在哪
一开始没有想通这个问题,但是如果将一个位置与矩阵中心联系起来就有思路了
以下的左边是位置与中心的相对位置,比如第一个就是矩阵左边终点,它会跑到矩阵上面终点
(-n,0) (0,n)
(-n,-n) (-n.n)
(-n,n) (n,n)
(-1,0) (0,1)
(-2,1) (1,2)
(i,j) (j,-i)
经过归纳后,发现原来相对位置为(i,j),后来就转到了 (j,-i)
接下来研究绝对位置,k为矩阵一半的长度,i,j为相对中心的位置,绝对位置为k+i,k+j)
比如长度为4 左上角 (0,0) 相对位置(-2,-2) 绝对位置(-2+2,-2+2)
所以转到(k+j,k-i)
而对于数组矩阵来说,矩阵长度为length-1,即2k=length-1
k-i=2k-(k+i)
所以原位置(x,y)变为 (y,length-1-x)
(k+i,k+j) (k+j,k-i)
(x,y) (y,length-1-x)
知道了位置变换的具体位置,现在进行旋转
具体思路是旋转某一区域的所有的数,连续旋转4次,让所有的数都被覆盖到
但是length为奇数时,有奇数个
将区域设定为竖条形
0<=i<(length-1)/2
0<=j<(length+1)/2
5
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
length为偶数时
0<=i
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
解法1(成功,2ms,很快)
速度为o(length^2)
具体思路如上所示,实际操作每次转为设定之前和之后的i,j,temp
package pid048;
import java.util.HashMap;
public class Solution {
public void rotate(int[][] matrix) {
int length=matrix.length;
int endi;
int endj;
if(length==0||length==1){
return;
}
if(length%2==1){
endi=(length-1)/2;
endj=(length+1)/2;
}
else{
endi=length/2;
endj=length/2;
}
int nowtemp;
int nexttemp;
int nowi;
int nowj;
int toi;
int toj;
for(int i=0;i
解法2 别人的
本方法按照两条线进行对称,方法很巧妙
通过实际数据分析,通过两个步骤的元素交换可实现目标:
按照副主对角线,将对称元素交换
按照行,将对称列元素全部交换
即可达到,使得二维矩阵,本地旋转90个角度。
注意坐标转换规则
public void rotate(int[][] matrix) {
if (matrix == null)
return;
int n = matrix.length;
// 沿着副对角线旋转
for (int i = 0; i < n; i++)
for (int j = 0; j < n - i; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[n - 1 - j][n - 1 - i];
matrix[n - 1 - j][n - 1 - i] = temp;
}
// 沿着中间水平线旋转
for (int i = 0; i < n / 2; i++)
for (int j = 0; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[n - 1 - i][j];
matrix[n - 1 - i][j] = temp;
}
}
解法3 别人的
一层层循环
这道题木有什么难度,原地顺时针旋转一个矩阵90度,要求时间复杂度O(n2),空间复杂度O(1)
两层循环,外层循环每循环一次旋转“一层”,逐步向里旋转。就酱,代码如下:
public class Solution {
public void rotate(int[][] matrix) {
int n = matrix.length;
int temp = 0;
for(int i = 0; i <= (n-1)/2 ; i++ ){
for(int j = i ; j < n - 1 - i; j++){
temp = matrix[i][j];
matrix[i][j] = matrix[n-1-j][i];
matrix[n-1-j][i] = matrix[n-1-i][n-1-j];
matrix[n-1-i][n-1-j] = matrix[j][n-1-i];
matrix[j][n-1-i] = temp;
}
}
}
}