面试题 01.07. Rotate Matrix LCCI
仅供自己学习
思路:
开一个同样大小的矩阵,根据规律在新矩阵赋值,在复制给原矩阵。根据观察可以得到,第 i 行第 j 列反转90度,会在第 j 行倒数第 i 列。即new[ j ][col-i -1]=matrix[i][j];
代码:
1 class Solution { 2 public: 3 void rotate(vector<vector<int>>& matrix) { 4 const int row=matrix.size(),col=matrix[0].size(); 5 vector<vector<int>> res(row,vector<int>(col)); 6 for(int i=0;i<row;++i){ 7 for(int j=0;j<col;++j){ 8 res[j][col-i-1]=matrix[i][j]; 9 } 10 } 11 matrix=res; 12 } 13 };
另一种原地算法是通过旋转的方法。我们将矩阵划分为4份,如果是偶数可以4份平分。如果是奇数,左上部分n/2+1的长度和n/2宽度。然后相当于这四份按照顺时针在和另外三份旋转交换一次值。
因为每次90度反转,会得到 [ i ][ j ]旋转到的位置为[j][n-i-1],[n-i-1][n-j-1],[n-j-1][i]。奇偶都使用,因为奇数时也只是多了中间的一份,而中心轴的那份,也是满足这样的关系和垂直该点所在中心轴的中心轴的元素交换。可以根据这个关系 画图推一下即可明白
代码:
1 class Solution { 2 public: 3 void rotate(vector<vector<int>>& matrix) { 4 const int n=matrix.size(); 5 int maxr=(n>>1)-1; //为了得到左上的那份分到的行数 6 int maxc=(n-1)>>1; //为了得到左上那份分到的列数 7 for(int i=maxr;i>=0;--i){ 8 for(int j=maxc;j>=0;--j){ 9 swap(matrix[i][j],matrix[j][n-i-1]); 10 swap(matrix[i][j],matrix[n-i-1][n-j-1]); 11 swap(matrix[i][j],matrix[n-j-1][i]); 12 } 13 } 14 } 15 };
同样的,交换可以通过一个中间变量来更换,所以把swap用一个变量代替也可以
还可根据第一个方法的关系new[ j ][col-i -1]=matrix[i][j]。通过水平中心轴对称后再通过主对角线对称得到。因为 matrix[ i ][ j ]通过水平中心轴反转得到matrix[col-i-1][j],再通过主对角线对称的到maxtrix[ j ][col-i -1]。主对角线对称是关于[0][0]和[n][n]连线对称
代码:
1 class Solution { 2 public: 3 void rotate(vector<vector<int>>& matrix) { 4 int n = matrix.size(); 5 // 水平翻转 6 for (int i = 0; i < n / 2; ++i) { 7 for (int j = 0; j < n; ++j) { 8 swap(matrix[i][j], matrix[n - i - 1][j]); 9 } 10 } 11 // 主对角线翻转 12 for (int i = 0; i < n; ++i) { 13 for (int j = 0; j < i; ++j) { 14 swap(matrix[i][j], matrix[j][i]); 15 } 16 } 17 } 18 };

浙公网安备 33010602011771号