rotate-image
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?
分析:将二维数组顺时针旋转90度。
首先,找规律。
当n=1时,不用动;
当n=2时,{1,2;3,4;}旋转之后为{3,1;2,4;},此时,初步总结规律为a[i][j]=a[n-1-j][i].
当n=3时,image旋转后变为新的image,可以验证上式的正确性。
当n=4,5,6...也是满足的。
如果不考虑空间复杂度的话,可以构建一个中间二维数组b[n][n],利用公式b[j][n-1-i]=a[i][j].
代码如下:
void rotate(vector<vector<int> > &matrix)
{
int n=matrix.size();
int *b=new int[n][n];
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
b[j][n-1-i]=matrix[i][j];
}
}
//再赋值回matrix
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
matrix[i][j]=b[i][j];
}
}
}
但题目要求空间复杂度为o(1),即只能在原数组上进行旋转。
以n=3为例,当一个元素发生旋转时,可以看出每个值旋转会影响到以下几个数:
a[i][j]---->a[j][n-1-i]---->a[n-1-i][n-1-j]---->a[n-1-j][i]---->a[i][j]
每个数旋转的时候会影响到其他三个数。所以引入一个临时变量tem就可以解决四个数的顺时针交换。
int tem=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]=tem;
现在的问题就是如何完整的把所有数都旋转90度且不会多旋转。继续分析:
当n=1时,无需旋转;
当n=2时,只需完成a[0][0]的旋转,就完成了整个数组的旋转。
当n=3时,需要旋转a[0][0]和a[0][1]的旋转,就完成了整个数组的旋转。
当n=4时,需要旋转a[0][0],a[0][1],a[0][2]和a[1][1]的旋转,就完成了整个数组的旋转。
.......
大致可以总结出这么一个规律:
i<n/2; 并且i<=j<n-1-i;
代码部分如下所示:
void rotate(vector<vector<int> > &matrix)
{
int n=matrix.size();
for(int i=0;i<n/2;i++)
{
for(int j=i;j<n-i-1;j++)
{
int tem=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]=tem;
}
}
}