1. 程式人生 > 其它 >面試題 01.07. 旋轉矩陣

面試題 01.07. 旋轉矩陣

《程式設計師面試金典》的第七題

主要就是涉及矩陣的知識點:矩陣旋轉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;
    }
}