有一副由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