题目链接--------------->leetcode----面试题 01.07. 旋转矩阵
这个题只要我们自己手动模拟一边旋转过程,很容易就找出规律来。
方法一:对于一个 n u m [ i ] [ j ] num[i][j] num[i][j]来说它旋转后的位置为 n u m [ j ] [ n − 1 − i ] num[j][n-1-i] num[j][n−1−i],我们使用一个数组来保存原数组的值,然后双重循环对原数组赋值即可。
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size(),m = matrix[0].size();
vector<vector<int>> num(matrix.begin(),matrix.end());
for(int i = 0;i < n;i++)
{
for(int j = 0;j < m;j++)
{
matrix[j][n - 1 - i] = num[i][j];
}
}
}
方法二:上述方法要使用额外数组,是因为在转换的过程中会把目标位置的数给覆盖掉,所以要使用一个数组来保存它们的值。其实完全没必要多用一个数组,我们可以看下述例子
假设我们即将要旋转的数字为 n u m [ i ] [ j ] num[i][j] num[i][j]
1. n u m [ i ] [ j ] num[i][j] num[i][j]被旋转到的位置为 n u m [ j ] [ n − 1 − i ] num[j][n-1-i] num[j][n−1−i]
2. n u m [ j ] [ n − 1 − i ] num[j][n-1-i] num[j][n−1−i]被旋转到的位置为 n u m [ n − 1 − i ] [ n − 1 − j ] num[n-1-i][n-1-j] num[n−1−i][n−1−j]
3. n u m [ n − 1 − i ] [ n − 1 − j ] num[n-1-i][n-1-j] num[n−1−i][n−1−j]被旋转到的位置为 n u m [ n − 1 − j ] [ i ] num[n-1-j][i] num[n−1−j][i]
4. n u m [ n − 1 − j ] [ i ] num[n-1-j][i] num[n−1−j][i]被旋转到的位置为 n u m [ i ] [ j ] num[i][j] num[i][j]
我们可以发现这是一个闭环,所以在对一个数字旋转时,为了避免目标位置的数字被覆盖我们可以一次将这四个数全部都旋转。此时我们并不需要一个二维数组,而只需要一个变量
由于我们一次需要操作便可旋转4个数,所以我们要确定枚举的边界。我们对于一个需要旋转的二维数组通过上述方法来模拟一遍,很容易就找到边界。
第一层的边界为
n
/
2
n/2
n/2,第二层的边界为
n
−
1
−
i
n-1-i
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 - 1 - i;j++)
{
int tmp = matrix[j][n - 1 - i];
matrix[j][n - 1 - i] = 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] = tmp;
}
}
}
看了题解后发现还有一种更好的做法
方法三:我们对二维数组先水平翻转,然后再按主对角线翻转。
水平翻转: n u m [ n − 1 − i ] [ j ] = n u m [ i ] [ j ] num[n-1-i][j]=num[i][j] num[n−1−i][j]=num[i][j],主对角线反转: n u m [ j ] [ i ] = n u m [ i ] [ j ] num[j][i]=num[i][j] num[j][i]=num[i][j]。
将上面两个式子合并可得到 n u m [ j ] [ n − 1 − i ] = n u m [ i ] [ j ] num[j][n-1-i]=num[i][j] num[j][n−1−i]=num[i][j],可以看出这正是我们方法一中的式子。
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
for(int i = 0;i < n/2;i++)
{
for(int j = 0;j < n;j++)
{
swap(matrix[i][j],matrix[n - 1 - i][j]);
}
}
for(int i = 0;i < n;i++)
{
for(int j = i;j < n;j++)
swap(matrix[i][j],matrix[j][i]);
}
}