1 解题思想
这道题呢,是让一个图像(二维数组),翻转90度,原地的
这道题如果不要求原地,那么我们可以重新开一个数组填入,单着明显不满足原地移动的要求。
仔细观察,二维数组我们可以看成是一圈,一圈的数据,如n=3,n=4时,都有两个圈,这里就叫做1环和2环吧,如果n更多,环会更多些。
对于每一环,旋转90度的操作,等于这个数字在环上移动(n-1)步,但是我们如何计算这个环上走的位置呢?
这时候我们用四个变量来表示环的位置,左边(列),右边(列),上边(行),下边(行)的位置。
我们从左上角开始,按照左上这一行,循环移动n-1次数据,每次都能正好移动完成(上边的行-》右边-》下边-》左边),这两做n-1次流程就好了
具体的变换,大家看代码
2 原题
You are given an n x n 2D matrix representing an image.
Rotate the image by 90 degrees (clockwise).
Follow up:
Could you do this in-place?
3 AC解
public class Solution {
/**
* 1 2 3
* 4 5 6
* 7 8 9
* ->
* 7 4 1
* 8 5 2
* 9 6 3
*
* 1 2 3 4
* 5 6 7 8
* 9 10 11 12
* 13 14 15 16
*
* ->
* 13 9 5 1
* 14 10 6 2
* 15 11 7 3
* 16 12 8 4
*
* 变换规则可以看到,可以有两种理解方式:
* 1、行列的颠倒
* 或者
* 2、按照圈的方式移动
*
* 第一种方式要借助一个临时的矩阵存储,不满足原地。。我想试试第二种满足么
*
* 注意需要两个常量保存,因为要进行原地替换,分别保存当前的值和上一个被替换掉的
* 只需要按照一个方向扫描n-1长度的数值,然后按照90度分别替换4个值就可以了,大家可以自行画图
*
* 具体的坐标变换我已经在代码里写了
*
*
* */
public void rotate(int[][] matrix) {
int n=matrix.length;
if(n<2)
return ;
int m=n/2; //圈数
//每一圈的行列信息
int edgeTop=0,edgeBottom=n-1,edgeLeft=0,edgeRight=n-1;
while(m-->0){
//从最左上角还是移动,一次移动四个
int tmp=0,last=0;
for(int i=edgeLeft;i<=edgeRight-1;i++){
//第一个移动是[top,i]->[i,right]
tmp=matrix[i][edgeRight];
matrix[i][edgeRight]=matrix[edgeTop][i];
last=tmp;
//第二个是[i,right]->[bottom,right-(i-edgeLeft)]
tmp=matrix[edgeBottom][edgeRight-(i-edgeLeft)];
matrix[edgeBottom][edgeRight-(i-edgeLeft)]=last;
last=tmp;
//第三个是[bottom,right-(i-edgeLeft)]->[bottom-(i-edgeLeft),left]
tmp=matrix[edgeBottom-(i-edgeLeft)][edgeLeft];
matrix[edgeBottom-(i-edgeLeft)][edgeLeft]=last;
//会后一个则是移动到开始的
matrix[edgeTop][i]=tmp;
}
edgeTop++;
edgeBottom--;
edgeLeft++;
edgeRight--;
}
}
}