面試題 01.07. 旋轉矩陣
阿新 • • 發佈:2021-12-22
《程式設計師面試金典》的第七題
主要就是涉及矩陣的知識點:矩陣旋轉90度。
第一種解法:輔助矩陣法
最簡單的一種解法,主要思想就是用輔助矩陣記錄元素旋轉後的位置,但這樣做的話,空間複雜度就為O(N^2)
注意一下對應位置,matrix[j][n-1-i]是旋轉後的位置,因此需要在輔助矩陣的這個位置,輸入對應的 matrix[i][j]。
class Solution { public void rotate(int[][] matrix) { int[][] m = new int[matrix.length][matrix[0].length]; //輔助矩陣// matrix[i][j] 旋轉90度後的位置為 matrix[j][n-1-i] int n = matrix.length; for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ m[j][n-1-i] = matrix[i][j]; //把輔助矩陣旋轉對應的位置放入元素 } } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ matrix[i][j]= m[i][j]; //複製輔助矩陣 } } } }
第二種解法:線性代數性質
線性代數性質,先通過水平軸翻轉,然後再通過主對角線反轉,可以得到對應旋轉90度的矩陣。
class Solution { public void rotate(int[][] matrix) { int n = matrix.length; // 水平翻轉 for (int i = 0; i < n / 2; ++i) { for (int j = 0; j < n; ++j) {int temp = matrix[i][j]; matrix[i][j] = matrix[n - i - 1][j]; matrix[n - i - 1][j] = temp; } } // 主對角線翻轉 for (int i = 0; i < n; ++i) { for (int j = 0; j < i; ++j) { int temp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = temp; } } } }
方法三:一圈一圈地調整資料
這是最複雜的一種方法,它的主要思想是:每次修改矩陣的一圈資料,然後再修改下一圈,直到沒有圈為止(一個或者零個元素)。 就和樹的年輪一樣。
主要程式碼思路:
temp = top[i]; //用一個臨時變數儲存 top[i] = left[i]; left[i] = bottom[i]; bottom[i] = right[i]; right[i] = temp;
每次從左上角開始修改(因此需要一個臨時變數記住左上角的元素),然後是左下角,右下角,右上角,進行 圈的邊長 - 1次 (兩行共佔一格,少一次遍歷) 修改,就可以進行下一圈了。
class Solution { public void rotate(int[][] matrix) { if(matrix.length==0||matrix.length!=matrix[0].length){ //長度為0或不是N*N矩陣 return; } int n = matrix.length; //矩陣級數 for(int i = 0;i<n/2;i++){ //總共要轉 n/2 圈 for(int j = i;j<n-1-i;j++){ //用臨時變數記錄要被覆蓋的值(左上方開始) int top = matrix[i][j]; //左邊(左下角開始)的值覆蓋上邊的值, 注意左邊的資料,行在變化而列不變(一直是第一行) matrix[i][j] = matrix[n-1-j][i]; //下邊(右下角開始)的值覆蓋左邊的值,注意下邊的資料,行一直是最後一行,而列在變化 matrix[n-1-j][i] = matrix[n-1-i][n-1-j]; //右邊(右上角開始)的值覆蓋下邊的值, 右邊的列一直是最後一列,行不斷變化,始終為j matrix[n-1-i][n-1-j] = matrix[j][n-1-i]; //上邊(左上角開始)的值覆蓋右邊的值 matrix[j][n-1-i] = top; } } return; } }