旋转图像
辅助矩阵
我们通过分析示例可以看出,转换后的矩阵和转换前的矩阵有如下关系
我们可以得出对于矩阵中第i行j列的元素,在旋转后出现在倒数第i列第j行的位置,我们可以得到如下关系。
所以我们可以使用一个辅助矩阵来进行旋转。
我们就会有如下代码:
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int n=matrix.size();
vector<vector<int>>ans=matrix;
for(int i=0;i<n;++i)
{
for(int j=0;j<n;++j)
{
ans[j][n-i-1]=matrix[i][j];
}
}
matrix=ans;
}
};
但是,题目要求我们必须原地旋转也就是意味着不能使用辅助矩阵。
原地旋转
在辅助矩阵中有matrix_new[j][n - i - 1] = matrix[i][j];这一公式,如果我们直接将matrix[i][j]放到matrix[j][n - i - 1] 中,原矩阵自中的matrix[j][n - i - 1]位置的值将会被原matrix[i][j]的值替换,这样在进行下次旋转的时候matrix[j][n - i - 1]位置的值就不是原来的值,就会出现错误,所以我们需要使用一个临时temp变量来暂存原matrix[j][n - i - 1]位置的值,这样我们在下次旋转的时候还可以得到原matrix[j][n - i - 1]位置的值(temp)。就会有如下公式:
那么matrix[col][n−row−1]的值会旋转到哪里呢?带入关键公式中
得matrix[n−row−1][n−col−1]=matrix[col][n−row−1],这样直接赋值还是会覆盖掉原matrix[n−row−1][n−col−1]中的值,因此还是需要临时值进行存储原matrix[n−row−1][n−col−1]的值。
循环带入得
matrix[n−col−1][row] 经过旋转操作之后回到哪个位置呢?
带入关键公式得matrix[row][col]=matrix[n−col−1][row],所以我们又回到了起始位置。
所以就有如下图:
因此我们使用临时变量来进行辅助旋转。
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
for (int i = 0; i < n / 2; ++i) {
for (int j = 0; j < (n + 1) / 2; ++j) {
int temp = matrix[i][j];
matrix[i][j] = matrix[n - j - 1][i];
matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1];
matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1];
matrix[j][n - i - 1] = temp;
}
}
}
};
用翻转代替旋转
根据示例2进行讲解
首先我们通过水平轴翻转得:
然后在根据主对角线进行翻转得:
有如下公式:
class Solution {
public:
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 - i - 1][j]);
}
}
// 主对角线翻转
for (int i = 0; i < n; ++i) {
for (int j = 0; j < i; ++j) {
swap(matrix[i][j], matrix[j][i]);
}
}
}
};