如何在 java 中逆时针旋转矩阵 90 度?
How do I rotate a matrix 90 degrees counterclockwise in java?
我正在尝试解决 Cracking the Coding Interview 一书中的问题。其中一个问题要求我将矩阵顺时针旋转 90 度。现在,在巩固我对矩阵旋转的理解的同时,我尝试着手解决一个新问题:尝试将矩阵逆时针(另一个方向)旋转90度。
我尝试遍历方阵的层,即外层,一直迭代到内层,并逐一旋转“正方形”每一侧的所有索引。这基本上是 Gayle Laakman McDowell 的解决方案所实现的,但另一个方向。
public static void rotateMatrix(int[][] matrix) {
if (matrix.length == 0) {
return;
}
for (int i = 0; i < matrix.length / 2; i++) {
int top = i;
int bottom = matrix.length - 1 - i;
for (int j = top; j < bottom; j++) {
int temp = matrix[top][j];
matrix[top][j] = matrix[j][matrix.length - 1 - j];
matrix[j][matrix.length - 1 - j] = matrix[bottom][j];
matrix[bottom][j] = matrix[j][matrix.length - 1 - bottom];
matrix[j][matrix.length - 1 - bottom] = temp;
}
}
}
我期望样本矩阵的结果
[1,2,3]
[4,5,6]
[7,8,9]
成为
[3,6,9]
[2,5,8]
[1,4,7]
但我的代码导致
[1,5,7]
[2,8,6]
[3,4,9]
我的代码中的 flaw/discrepancy 在哪里?
如果您画出矩阵进行可视化,您会发现您的某些索引已关闭。例如,您应该在更新中使用 bottom 而不是使用 matrix.length-1
,因为图层正方形的大小会随着 i
的增加而减小。另一个错误是,在您的第二次更新中,您应该:
matrix[j][bottom] = matrix[bottom][bottom - (j - top)];
而不是:
matrix[j][bottom] = matrix[bottom][j];
这是因为在图层的底行中,索引从最后一列开始并向后移动到第一列。 j - top
表示您在图层顶行的距离。
画出矩阵后,发现正确的更新如下:
public static void main(String[] args) {
int n = 5;
int[][] a = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = i * n + j + 1;
}
}
rotateMatrix(a);
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
System.out.printf("%3d", a[i][j]);
}
System.out.println();
}
}
public static void rotateMatrix(int[][] matrix) {
if (matrix.length == 0) {
return;
}
for (int i = 0; i < matrix.length / 2; i++) {
int top = i;
int bottom = matrix.length - 1 - i;
for (int j = top; j < bottom; j++) {
int temp = matrix[top][j];
matrix[top][j] = matrix[j][bottom];
matrix[j][bottom] = matrix[bottom][bottom - (j - top)];
matrix[bottom][bottom - (j - top)] = matrix[bottom - (j - top)][top];
matrix[bottom - (j - top)][top] = temp;
}
}
}
输出:
5 10 15 20 25
4 9 14 19 24
3 8 13 18 23
2 7 12 17 22
1 6 11 16 21
将矩阵旋转 90 度类似于转置。 [i][j]
的索引变为 [j][i]
,但其中一侧的索引变为等于 the length of the side, minus 1, minus the current index of the side
。索引从 0 开始。
int m = 5;
int n = 4;
int[][] arr1 = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16},
{17, 18, 19, 20}};
int[][] arr2 = new int[n][m];
int[][] arr3 = new int[n][m];
IntStream.range(0, m).forEach(i ->
IntStream.range(0, n).forEach(j -> {
// turn matrix 90º clockwise ⟳
arr2[j][m - 1 - i] = arr1[i][j];
// turn matrix 90º anticlockwise ⟲
arr3[n - 1 - j][i] = arr1[i][j];
}));
// Output to the markdown table:
String[] matrices = Stream.of(arr1, arr2, arr3)
.map(arr2d -> Arrays.stream(arr2d)
.map(arr -> Arrays.stream(arr)
.mapToObj(i -> String.format("%2d", i))
.toArray())
.map(Arrays::toString)
.collect(Collectors.joining("<br>")))
.toArray(String[]::new);
System.out.println("| original matrix | turn matrix 90º ⟳ | turn matrix 90º ⟲ |");
System.out.println("|---|---|---|");
System.out.println("|<pre>" + String.join("</pre>|<pre>", matrices) + "</pre>|");
original matrix
turn matrix 90º ⟳
turn matrix 90º ⟲
[ 1, 2, 3, 4]
[ 5, 6, 7, 8]
[ 9, 10, 11, 12]
[13, 14, 15, 16]
[17, 18, 19, 20]
[17, 13, 9, 5, 1]
[18, 14, 10, 6, 2]
[19, 15, 11, 7, 3]
[20, 16, 12, 8, 4]
[ 4, 8, 12, 16, 20]
[ 3, 7, 11, 15, 19]
[ 2, 6, 10, 14, 18]
[ 1, 5, 9, 13, 17]
我正在尝试解决 Cracking the Coding Interview 一书中的问题。其中一个问题要求我将矩阵顺时针旋转 90 度。现在,在巩固我对矩阵旋转的理解的同时,我尝试着手解决一个新问题:尝试将矩阵逆时针(另一个方向)旋转90度。
我尝试遍历方阵的层,即外层,一直迭代到内层,并逐一旋转“正方形”每一侧的所有索引。这基本上是 Gayle Laakman McDowell 的解决方案所实现的,但另一个方向。
public static void rotateMatrix(int[][] matrix) {
if (matrix.length == 0) {
return;
}
for (int i = 0; i < matrix.length / 2; i++) {
int top = i;
int bottom = matrix.length - 1 - i;
for (int j = top; j < bottom; j++) {
int temp = matrix[top][j];
matrix[top][j] = matrix[j][matrix.length - 1 - j];
matrix[j][matrix.length - 1 - j] = matrix[bottom][j];
matrix[bottom][j] = matrix[j][matrix.length - 1 - bottom];
matrix[j][matrix.length - 1 - bottom] = temp;
}
}
}
我期望样本矩阵的结果
[1,2,3]
[4,5,6]
[7,8,9]
成为
[3,6,9]
[2,5,8]
[1,4,7]
但我的代码导致
[1,5,7]
[2,8,6]
[3,4,9]
我的代码中的 flaw/discrepancy 在哪里?
如果您画出矩阵进行可视化,您会发现您的某些索引已关闭。例如,您应该在更新中使用 bottom 而不是使用 matrix.length-1
,因为图层正方形的大小会随着 i
的增加而减小。另一个错误是,在您的第二次更新中,您应该:
matrix[j][bottom] = matrix[bottom][bottom - (j - top)];
而不是:
matrix[j][bottom] = matrix[bottom][j];
这是因为在图层的底行中,索引从最后一列开始并向后移动到第一列。 j - top
表示您在图层顶行的距离。
画出矩阵后,发现正确的更新如下:
public static void main(String[] args) {
int n = 5;
int[][] a = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = i * n + j + 1;
}
}
rotateMatrix(a);
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
System.out.printf("%3d", a[i][j]);
}
System.out.println();
}
}
public static void rotateMatrix(int[][] matrix) {
if (matrix.length == 0) {
return;
}
for (int i = 0; i < matrix.length / 2; i++) {
int top = i;
int bottom = matrix.length - 1 - i;
for (int j = top; j < bottom; j++) {
int temp = matrix[top][j];
matrix[top][j] = matrix[j][bottom];
matrix[j][bottom] = matrix[bottom][bottom - (j - top)];
matrix[bottom][bottom - (j - top)] = matrix[bottom - (j - top)][top];
matrix[bottom - (j - top)][top] = temp;
}
}
}
输出:
5 10 15 20 25
4 9 14 19 24
3 8 13 18 23
2 7 12 17 22
1 6 11 16 21
将矩阵旋转 90 度类似于转置。 [i][j]
的索引变为 [j][i]
,但其中一侧的索引变为等于 the length of the side, minus 1, minus the current index of the side
。索引从 0 开始。
int m = 5;
int n = 4;
int[][] arr1 = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16},
{17, 18, 19, 20}};
int[][] arr2 = new int[n][m];
int[][] arr3 = new int[n][m];
IntStream.range(0, m).forEach(i ->
IntStream.range(0, n).forEach(j -> {
// turn matrix 90º clockwise ⟳
arr2[j][m - 1 - i] = arr1[i][j];
// turn matrix 90º anticlockwise ⟲
arr3[n - 1 - j][i] = arr1[i][j];
}));
// Output to the markdown table:
String[] matrices = Stream.of(arr1, arr2, arr3)
.map(arr2d -> Arrays.stream(arr2d)
.map(arr -> Arrays.stream(arr)
.mapToObj(i -> String.format("%2d", i))
.toArray())
.map(Arrays::toString)
.collect(Collectors.joining("<br>")))
.toArray(String[]::new);
System.out.println("| original matrix | turn matrix 90º ⟳ | turn matrix 90º ⟲ |");
System.out.println("|---|---|---|");
System.out.println("|<pre>" + String.join("</pre>|<pre>", matrices) + "</pre>|");
original matrix | turn matrix 90º ⟳ | turn matrix 90º ⟲ |
---|---|---|
[ 1, 2, 3, 4] |
[17, 13, 9, 5, 1] |
[ 4, 8, 12, 16, 20] |