トピック
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;
}
}
}