正方行列回転 (48) 解

トピック

N × N各ピクセルのサイズが 4 バイトの行列で表される画像が与えられます。画像を90度回転するアルゴリズムを設計してください。

余分なメモリ領域を占有せずに実行できますか?

例 1:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]

例 2:

给定 matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

原地旋转输入矩阵,使其变为:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

分析する

指定された行列の形状はN x N正方行列であるため、その幅と高さが既知であり、回転度がN必要な場合、配列が変更され、充填方法も変更されます90横向排列竖向排列倒序填充

図に示すように:

ここに画像の説明を挿入

変換後、水平の添字は逆の順序で垂直の添字になります。式は次のとおりです。横向index = 竖向N-1-index

コード

O(n²)空の行列に時間計算量:空間計算量:を受け入れることができれば、それは非常に簡単です。O(2n)

    public void rotate(int[][] matrix) {
    
    
        int[][] result = new int[matrix.length][matrix.length];
        for (int i = 0; i < matrix.length; i++) {
    
    
            int now[] = matrix[i];
            // 计算旋转后下标
            int index = matrix.length-1-i;
            for (int j = 0; j < now.length; j++) {
    
    
                result[j][index] = now[j];
            }
        }
    }

原地旋转また、タイトルでは余分なスペースに適応しないようにする必要があるため、一時行列は使用できず、指定された行列、つまり、時間計算量:O(n²)空間計算量:内で回転する必要があります。O(1)

その場で回転させると一部の値がカバーされてしまうため、上書きされた値も保存する必要があります。上記の行で直接オーバーレイ調整を行うと、過剰なオーバーレイ値が生成されるため、上書きされた値も保存する必要があります値を 1 つずつ正しい位置に修正します。各行の1桁目から調整してください。

ここに画像の説明を挿入

コードは以下のように表示されます。

    public void rotate(int[][] matrix) {
    
    
        int length = matrix.length;
        for (int i = 0; i < matrix.length/2; i++) {
    
    
            for (int j = i; j < matrix.length - (i + 1); j++) {
    
    
                int temp = matrix[i][j];
                matrix[i][j] = matrix[length - j-1][i];
                matrix[length - j -1][i] = matrix[length-i-1][length-j-1];
                matrix[length-i-1][length-j-1] = matrix[j][length-i-1];
                matrix[j][length-i-1] = temp;
            }
        }
    }

別の方法もあります正方形旋转90°= 正方形水平反转+ 对角线反转; 時間計算量:O(n²)空間計算量:O(1)

ここに画像の説明を挿入

コードは以下のように表示されます。

    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;
            }
        }
    }

おすすめ

転載: blog.csdn.net/AnNanDu/article/details/126740146