描述:一个n*n的矩阵,将其顺时针转90°(不允许申请额外的矩阵)
Example:
Given input matrix = [ [1,2,3], [4,5,6], [7,8,9] ], rotate the input matrix in-place such that it becomes: [ [7,4,1], [8,5,2], [9,6,3] ] | Given input matrix = [ [ 5, 1, 9,11], [ 2, 4, 8,10], [13, 3, 6, 7], [15,14,12,16] ], rotate the input matrix in-place such that it becomes: [ [15,13, 2, 5], [14, 3, 4, 1], [12, 6, 8, 9], [16, 7,10,11] ] |
考虑这个题的时候可以先手动算一下顺时针旋转90°的过程,会发现旋转是按层进行的,从最外层到最里层,因此比较容易想到的做法就是dfs:
以下是我的代码,需要手动计算进行理解:
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
rotate(matrix, 0, matrix.size() - 1);
}
void rotate(vector<vector<int>>& matrix, int start, int end)
{
if(end == start || start > end)
return;
for(int i = 0; i < end - start; i++) //这里i的范围一定要注意,因为start不一定是从0开始的
{
int tmp = matrix[start][start + i];
matrix[start][start + i] = matrix[end - i][start];
matrix[end - i][start] = matrix[end][end - i];
matrix[end][end - i] = matrix[start + i][end];
matrix[start+i][end] = tmp;
}
rotate(matrix, start + 1,end - 1);
}
};
这种方法是通过复制来实现矩阵旋转,看解析的时候发现也可以通过交换来实现矩阵旋转:
1 2 3 4 13 9 5 4 13 9 5 4 13 9 5 1
5 8 3 8 16 8 16 2
9 12 => 2 12 => 15 12 => 15 3
13 14 15 16 1 14 15 16 14 3 2 1 14 12 8 4
6 7 10 7 10 7 10 6
10 11 => 6 11 => 11 6 => 11 7
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
for(int i = 0; i < n/2; i++) // for each loop
for(int j = i; j < n - i - 1; j++){
swap(matrix[i][j], matrix[n-1-j][i]);
swap(matrix[n-1-j][i], matrix[n-1-i][n-1-j]);
swap(matrix[n-1-i][n-1-j], matrix[j][n-1-i]);
}
}
};
巧妙地利用矩阵反转的特性,先沿主对角线翻转,再沿垂直中心线翻转
void rotate(vector<vector<int>>& matrix) {
for (unsigned int i=0; i<matrix.size(); i++) // transpose
for (unsigned int j=0; j<i; j++)
swap(matrix[i][j], matrix[j][i]);
for (auto& row: matrix) // reverse
reverse(row.begin(), row.end());
}
还有一种做法是利用vector的性质
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
for(int n = 0; n < matrix.size(); n++)
{
for(int m = matrix.size()-1; m >= 0; m--)
{
matrix[n].push_back(matrix[m][n]);
}
}
for(int n = 0; n < matrix.size(); n++)
{
matrix[n].erase(matrix[n].begin(),matrix[n].begin() + matrix.size());
}
}
};
以上除了第一种做法之外,均为leetcode Discuss区大神的方法,用来借鉴!