How do I rotate a matrix 90 degrees counterclockwise in java? [duplicate]
Asked Answered
A

2

0

I'm trying to go over the problems in the Cracking the Coding Interview book. One of the questions asks me to rotate a matrix 90 degrees clockwise. Now, while trying to solidify my understanding of matrix rotation, I tried to embark on a new problem: to try to rotate a matrix 90 degrees counterclockwise (the other direction).

I've tried to go through layers of a square matrix, the outer layer, iterating all the way into the inner layer and rotating all the indexes of each side of the "square" one by one. This basically is what Gayle Laakman McDowell's solution implemented, but the other direction.

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

I expected the result of a sample matrix

[1,2,3]
[4,5,6]
[7,8,9]

to be

[3,6,9]
[2,5,8]
[1,4,7]

but my code resulted in

[1,5,7]
[2,8,6]
[3,4,9]

Where is the flaw/discrepancy in my code?

Angelynanger answered 22/6, 2019 at 21:56 Comment(0)
P
2

If you draw out the matrix to visualize, you'll see that some of your indices are off. For example, instead of using matrix.length-1, you should use bottom in your updates because the size of the layer's square will decrease as i increases. Another error is that in your second update, you should have:

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

instead of:

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

This is because in the bottom row of the layer the indices start from the last column and move backward to the first column. j - top indicates how far along you are in the top row of your layer. After drawing out the matrix, I found the correct updates to be as follows:

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

Output:

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
Pastypat answered 22/6, 2019 at 23:4 Comment(0)
C
0

Rotating the matrix 90 degrees is similar to transposing. The indices of [i][j] become [j][i], but the indices of one of its sides becomes equal to the length of the side, minus 1, minus the current index of the side. Indexes start at 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]
Casease answered 23/12, 2020 at 23:37 Comment(1)
what are you using pre for? java console doesnt interpret htmlDinghy

© 2022 - 2024 — McMap. All rights reserved.