Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotate array clockwise

I have a two dimensional array that I need to rotate 90 degrees clockwise, however I keep getting arrayindexoutofbounds...

public int[][] rotateArray(int[][] arr) {
    // first change the dimensions vertical length
    // for horizontal length and vice versa
    int[][] newArray = new int[arr[0].length][arr.length];

    // invert values 90 degrees clockwise by starting
    // from button of array to top and from left to right
    int ii = 0;
    int jj = 0;
    for (int i = 0; i < arr[0].length; i++) {
        for (int j = arr.length - 1; j >= 0; j--) {
            newArray[ii][jj] = arr[i][j];
            jj++;
        }
        ii++;
    }
    return newArray;
}
like image 254
user69514 Avatar asked May 10 '10 00:05

user69514


People also ask

How do you rotate an array?

The array can be left rotated by shifting its elements to a position prior to them which can be accomplished by looping through the array and perform the operation arr[j] = arr[j+1]. The first element of the array will be added to the last of rotated array.

How do I rotate an array to the right?

The array can be right rotated by shifting its elements to a position next to them which can be accomplished by looping through the array in reverse order (loop will start from the length of the array -1 to 0) and perform the operation arr[j] = arr[j-1].

How do you rotate a right and left array?

Approach: In this method simply create a temporary array and copy the elements of the array arr[] from 0 to the (D-1)th index. After that move, the rest elements of the array arr[] from index D to N. Then move the temporary array elements to the original array.


2 Answers

Here's a standard matrix clockwise rotation code:

static int[][] rotateCW(int[][] mat) {
    final int M = mat.length;
    final int N = mat[0].length;
    int[][] ret = new int[N][M];
    for (int r = 0; r < M; r++) {
        for (int c = 0; c < N; c++) {
            ret[c][M-1-r] = mat[r][c];
        }
    }
    return ret;
}

Note a few things:

  • It improves readability to refer to the dimensions of a MxN matrix as M and N
  • It's traditional to use r, c instead of i, j to index row and column of a matrix
  • This is not the most robust implementation:
    • Does not ensure that mat is a valid MxN matrix, M>0, N>0
  • Use an explicit mapping formula instead of extraneous local variables
    • Makes program less complex and more readable

Here's a test harness:

import java.util.Arrays;
//...

static void printMatrix(int[][] mat) {
    System.out.println("Matrix = ");
    for (int[] row : mat) {
        System.out.println(Arrays.toString(row));
    }
}
public static void main(String[] args){
    int[][] mat = {
        { 1, 2, 3 },
        { 4, 5, 6 }
    };
    printMatrix(mat);
    // Matrix = 
    // [1, 2, 3]
    // [4, 5, 6]

    int[][] matCW = rotateCW(mat);
    printMatrix(matCW);
    // Matrix = 
    // [4, 1]
    // [5, 2]
    // [6, 3]
}

Note the use of the for-each loop and java.util.Arrays in printMatrix. You should definitely familiarize yourself with them if you're working with arrays a lot in Java.

Links to Java matrix libraries

If you're working with matrices a lot, you may want to consider using a specialized matrix library instead.

  • JAMA: http://math.nist.gov/javanumerics/jama/
  • UJMP: http://www.ujmp.org/

Related questions

Technically, Java has array of arrays. Make sure you understand all the implications.

  • Performance comparison of array of arrays vs multidimensional arrays
  • Java Arrays.equals() returns false for two dimensional arrays.
like image 172
polygenelubricants Avatar answered Sep 21 '22 17:09

polygenelubricants


I don't understand your loops' logic -- shouldn't it be

for (int i = 0; i < arr[0].length; i++) {
    for (int j = arr.length - 1; j >= 0; j--) {
        newArray[i][j] = arr[j][i];
    }
}

Net of whether each index goes up, like i here, or down, like j here (and of whether either or both need to be "flipped" in the assignment, e.g using arr.length-1-j in lieu of plain j on one side of the = in the assignment;-), since arr dimensions are arr.length by arr[0].length, and vice versa for newArray, it seems to me that the first index on arr (second on newArray) must be the one spanning the range from 0 to arr.length-1 included, and the other range for the other index.

This is a kind of "basic dimensional analysis" (except that "dimension" is used in a different sense than normally goes with "dimensional analysis" which refers to physical dimensions, i.e., time, mass, length, &c;-). The issue of "flipping" and having each loop go up or down depend on visualizing exactly what you mean and I'm not the greatest "mental visualizer" so I think, in real life, I'd try the various variants of this "axis transposition" until I hit the one that's meant;-).

like image 37
Alex Martelli Avatar answered Sep 23 '22 17:09

Alex Martelli