有一副由NxN矩阵表示的图像,这里每一个像素用一个int表示,请编写一个算法,在不占用额外内存空间的状况下(即不使用缓存矩阵),将图像顺时针旋转90度。
给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵,保证N小于等于500,图像元素小于等于256。
测试样例:c++
[[1,2,3],[4,5,6],[7,8,9]],3 返回:[[7,4,1],[8,5,2],[9,6,3]]
犯了一个很是大的错误,觉得全部的矩阵都是顺序排列的,这样的话经过找规律就能发现变换后矩阵的第一行其实就是原矩阵第一列的逆向表示,变换后矩阵后面的行就是对应第一行的+1表示:算法
1 2 3 7 4 1 4 5 6---------> 8 5 2 // 第二行就是第一行+1 7 8 9 9 6 3
class Transform { public: vector<vector<int> > transformImage(vector<vector<int> > mat, int n) { // write code here int temp=mat[0][0]; for(int i=0;i<n;i++) { if(n-1-i==0) mat[0][i]=temp; else mat[0][i]=mat[n-i-1][0]; } for(int i=1;i<n;i++) { for(int j=0;j<n;j++) { mat[i][j]=mat[i-1][j]+1; } } return mat; } };
先在原来代码上进行修补,加一个缓存矩阵后是能AC的,代码以下:缓存
class Transform { public: vector<vector<int> > transformImage(vector<vector<int> > mat, int n) { // write code here res=mat; for(int j=0;j<n;j++) { for(int i=0;i<n;i++) { if(n-1-i==0&&j==0) mat[j][i]=res[0][0]; else mat[j][i]=res[n-i-1][j]; } } return mat; } private: vector<vector<int>> res; };
可是题目要求的是"原地算法",因此须要更换算法,网上的代码以下:测试
public int[][] transformImage(int[][] mat, int n) { for (int layer = 0; layer < n / 2; ++layer) { int first = layer; int last = n - 1 - layer; for (int i = first; i < last; ++i) { int offset = i - first; // 存储上边 int top = mat[first][i]; // 左到上 mat[first][i] = mat[last - offset][first]; // 下到左 mat[last - offset][first] = mat[last][last - offset]; // 右到下 mat[last][last - offset] = mat[i][last]; // 上到右 mat[i][last] = top; } } return mat; }
这个代码就颇有意思,主要考虑了偏移量以及只用操做一半的矩阵就OK了。操做原理就是考虑矩阵的四个角落位置,而后加上偏移量继续变换,一层一层地往里面变换。code