如何在Java中将矩阵逆时针旋转90度?

时间:2019-06-22 21:56:05

标签: java matrix rotation

我正在尝试解决“破解编码面试”一书中的问题。问题之一要求我将矩阵顺时针旋转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]]
。 我的代码中的缺陷/差异在哪里?

3 个答案:

答案 0 :(得分:2)

如果绘制矩阵进行可视化,您会发现某些索引已关闭。例如,不要使用matrix.length-1,而应在更新中使用bottom,因为随着我的增加,图层正方形的大小将减小。另一个错误是,在第二次更新中,您应该具有:

matrix[j][bottom] = matrix[bottom][bottom - (j - top)];

代替:

matrix[j][bottom] = matrix[bottom][j];

这是因为在图层的底部行中,索引从最后一列开始,然后向后移动到第一列。 j-顶部表示您在图层顶行中的距离。 绘制出矩阵后,我发现正确的更新如下:

public class matrix {
    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

答案 1 :(得分:0)

您正在处理单个矩阵实例,请在矩阵中设置值,同时还要读取可能导致问题的旧值。

使函数返回新矩阵将使您的工作更加轻松。您的代码可能是:

public static int[][] rotateMatrix(int[][] m) {
    if(m.length == 0) return new int[0][0];

    int rows = m.length, cols = m[0].length;
    int[][] result = new int[cols][rows];

    for(int row = 0; row < cols; row++) {
        for(int col = 0; col < rows; col++) {
            result[row][col] = m[col][rows - row - 1];
        }
    }

    return result;
}

我还将int[][]数组封装在一个类中以实现不变性。

答案 2 :(得分:0)

将矩阵旋转 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>|");
<头>
原始矩阵 将矩阵旋转 90º ⟳ 将矩阵旋转 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]