14

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;
}
2
  • This is not a matrix rotation. It's a matrix transposition en.wikipedia.org/wiki/Transpose which is a reflection on the main diagonal. Commented May 10, 2010 at 1:47
  • This just reverses the rows, but jj has to be set to 0 for every i. To rotate exchange i with j in arr[i][j] (and don't forget to set jj to 0 Commented May 10, 2010 at 2:48

11 Answers 11

46

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.

Related questions

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

Sign up to request clarification or add additional context in comments.

2 Comments

How do i turn it counter clockwise
What makes this implementation "standard"? Is it published somewhere, or is this code supposed to be so simple that anyone who's not an idiot like me should just be able to figure out quickly?
18

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;-).

3 Comments

@user, you're welcome -- I did suspect I was missing some flipping and/or upside-down vs downside-up for either (or both?-) indices, as I mentioned in the 2nd paragraph;-).
newArray[i][j] = arr[j][i]; transposes the matrix. It should be newArray[i][length-1-j] = arr[j][i];
@MacieJ is correct. See my answer for a more thorough treatment of the problem.
4

jj++ is run i*j times, and that can't be good at all.

Try to reset jj in the outer loop.

Comments

1

Solution for generic objects:

public static <T> T[][] rotateArray90clockwise(Class<T> clas, T[][] array) {

    T[][] target = (T[][]) java.lang.reflect.Array.newInstance(
            clas, array[0].length, array.length);

    for (int i = 0; i < target.length; i++) {
        for (int j = 0; j < target[i].length; j++) {
            target[i][j] = array[(target[i].length - 1) - j][i];
        }
    }

    return target;
}

usage:

rotateArray90clockwise(Some.class,array);

Comments

1
static int[][] rotateClockwise(int[][] matrix) {
    int rowNum = matrix.length;
    int colNum = matrix[0].length;
    int[][] temp = new int[rowNum][colNum];
    for (int i = 0; i < rowNum; i++) {
        for (int j = 0; j < colNum; j++) {
            temp[i][j] = matrix[rowNum - j - 1][i];
        }
    }
    return temp;
}

Comments

0
public class RotateMatrix {

    static int index_of_rows;
    static int index_of_columns;
    static int number_of_rows;
    static int number_of_columns;

    public static void main(String[] args) {
        int[][] matrix={{1 ,2 ,3 ,4 ,5 },
                        {6 ,7 ,8 ,9 ,10},
                        {11,12,13,14,15},
                        {16,17,18,19,20},
                        {21,22,23,24,25}};
        index_of_rows = matrix.length -1;
        index_of_columns = matrix[0].length -1;
        number_of_rows = matrix.length;
        number_of_columns = matrix[0].length;


        RotateMatrix rm = new RotateMatrix();

        rm.printGrid(matrix);//before rotation
        rm.rotate360CW(matrix,rm);

    }

    public int[][] rotate90CW(int[][] matrix, RotateMatrix rm) {

        int[][] newMatrix = new int[number_of_rows][number_of_columns];
        int totalNumber = (number_of_rows) * (number_of_columns);
        int[] intArray = createSingleArray(matrix,totalNumber);


        int a =0;
            // kept index from out-of-bounds error; mod to:
            // number_of_columns-1
            // number_of_rows-1
        for(int c=number_of_columns-1; c>=0; c--) {
            for(int r=0; r<=number_of_rows-1; r++) {
                newMatrix[r][c] = intArray[a];
                a++;
            }
        }
        rm.printGrid(newMatrix);
        return newMatrix;
    }

    public int[] createSingleArray(int[][] matrix, int totalNumber) {
        int a=0;
        int[] intArray = new int[totalNumber];

        for(int b=0;b<=index_of_rows; b++) {
            for(int c=0; c<=index_of_columns;c++) {
                intArray[a] = matrix[b][c];
                a++;
            }
        }
        return intArray;
    }

    public void printGrid(int[][] matrix) {
        StringBuilder sb = new StringBuilder("--------------------------");

        for(int i =0; i<=index_of_rows; i++) {
            System.out.println(sb.toString());//print each row
            sb.delete(0, sb.length());//Then clear the row and build the next
            for(int j=0; j<=index_of_columns;j++) {
                sb.append(matrix[i][j]+",");
            }
        }
        System.out.println(sb.toString());

    }

    public int[][] rotate180CW(int[][] matrix, RotateMatrix rm) {
        return rm.rotate90CW(rm.rotate90CW(matrix, rm), rm);
    }

    public int[][] rotate270CW(int[][] matrix, RotateMatrix rm) {
        return rm.rotate90CW(rm.rotate90CW(rm.rotate90CW(matrix, rm), rm),rm);
    }

    public int[][] rotate360CW(int[][] matrix, RotateMatrix rm) {
        return rm.rotate90CW(rm.rotate90CW(rm.rotate90CW(rm.rotate90CW(matrix, rm),
                                                    rm),rm),rm);
    }
}

Comments

0

I completely understand that this question has nothing to do with Swift, but here's some verbose Swift 4:

    func clockwise(num:Int, square:[[Int]]) -> [[Int]] {
        var s = square
        if num == 0 {
            return s
        }
        for x in 0...(square.count - 1) {
            for y in 0...(square.count - 1) {
                s[x][y] = square[(square.count - 1) - y][x]
            }
        }
        return clockwise(num: num - 1, square: s)
    }
    func counterClockwise(num:Int, square:[[Int]]) -> [[Int]] {
        var s = square
        if num == 0 {
            return s
        }
        for x in 0...(square.count - 1) {
            for y in 0...(square.count - 1) {
                s[x][y] = square[y][(square.count - 1) - x]
            }
        }
        return counterClockwise(num: num - 1, square: s)
    }

This thread or whatever popped up when I searched for the question in Swift.

Comments

0

Steps to Rotate a matrix clockwise or Anti-Clockwise:

  1. Take Transpose of Given Matrix
  2. Swap columns vertical (if you want Clockwise Rotation) (OR)

Swap Columns Horizontal (if You want Anti-Clockwise Rotation)

Program For Clockwise Rotation:

//Program For Clockwise Rotation
import java.util.Scanner;

public class ClockWiseRotation {
    public static void main(String[] args) {
        int i, j, sw, n = 4;
        int a[][] = new int[6][6];
        int b[][] = new int[6][6];
        System.out.println("Enter the  elements for matrix\n");
        Scanner input = new Scanner(System.in);
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                a[i][j] = input.nextInt();
            }
        }
        System.out.println("The Matrix\n");
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                System.out.print(a[i][j] + "\t");
            }
            System.out.println("\n");
        }
        System.out.println("Transformation of given matrix\n");
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                b[i][j] = a[j][i];
            }
        }
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                System.out.print(b[i][j] + "\t");
            }
            System.out.println("\n");
        }
        System.out.println("Clockwise Rotation of given matrix\n");
        for (i = 0; i < n / 2; i++) {
            for (j = 0; j < n; j++) {
                sw = b[j][i];
                b[j][i] = b[j][n - 1 - i];
                b[j][n - 1 - i] = sw;
            }
            System.out.println("\n");
        }
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                System.out.print(b[i][j] + "\t");
            }
            System.out.println("\n");
        }
    }
}

Program For Anti-Clockwise Rotation

//Anti-Clockwise Rotation
import java.util.Scanner;

public class Anti_ClockWiseRotation {
    public static void main(String[] args) {
        int i, j, sw, n = 6;
        int a[][] = new int[6][6];
        int b[][] = new int[6][6];
        System.out.println("Enter the  elements for matrix\n");
        Scanner input = new Scanner(System.in);
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                a[i][j] = input.nextInt();
            }
        }
        System.out.println("The Matrix\n");
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                System.out.print(a[i][j] + "\t");
            }
            System.out.println("\n");
        }
        System.out.println("Transformation of given matrix\n");
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                b[i][j] = a[j][i];
            }
        }
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                System.out.print(b[i][j] + "\t");
            }
            System.out.println("\n");
        }
        System.out.println("Anti-Clockwise Rotation of given matrix\n");
        for (i = 0; i < n; i++) {
            for (j = 0; j < n / 2; j++) {
                sw = b[j][i];
                b[j][i] = b[n - 1 - j][i];
                b[n - 1 - j][i] = sw;
            }
            System.out.println("\n");
        }
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                System.out.print(b[i][j] + "\t");
            }
            System.out.println("\n");
        }
    }
}

n = Number of rows or Number of Columns

Where We can change the n, The above are worked only for square Matrix

Tested and Worked Well

Comments

0

Here my verified solution:

public int[][] rotateImage(int[][] a) {
    int colLenght = a[0].length;
    int rowLength = a.length;
    int[][] r = new int[rowLength][colLenght];

    for (int i = 0; i < a.length; i++) {
        for (int j = a.length - 1, rc = 0; j >= 0 && rc < a.length; j--, rc++) {
            r[i][rc] = a[j][i];
        }
    }
    return r;
}

Comments

0
int[] a = new int[]{10, 20, 30, 40, 50};
int temp = a[a.length - 1];
for (int i = a.length - 1; i > 0; i--) {
    a[i] = a[i - 1];
}
for (int i = 0; i < a.length; i++) {
    a[0] = temp;
    System.out.println("" + a[i]);
}

1 Comment

Hi, please add some explaination to your code to help the OP understand it
-2
public class Sample {

    /**
     * @param args
     */

    public static void main(String[] args) {
        // TODO Auto-generated method stub      
        int mat[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } };
        printMatrix(mat);

        int antiClockwiseMatrix[][] = rotateAntiClockwiseMatrix(mat);
        printMatrix(antiClockwiseMatrix);
        int clockwiseMatrix[][] = rotateClockwiseMatrix(mat);
        printMatrix(clockwiseMatrix);

        // rotateAntiMatrix(mat);
    }

    public static void printMatrix(int mat[][]) {
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat[0].length; j++) {
                System.out.print(mat[i][j] + "\t");
            }
            System.out.print("\n");
        }
        System.out.print("\n");

    }

    static public int[][] rotateAntiClockwiseMatrix(int mat[][]) {
        int rows = mat.length;
        int cols = mat[0].length;
        int newMat[][] = new int[cols][rows];
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                newMat[j][i] = mat[i][j];
            }
        }

        return newMat;
    }

    static public int[][] rotateClockwiseMatrix(int mat[][]) {
        int newMat[][] = rotateAntiClockwiseMatrix(mat);
        int finMat[][] = new int[newMat.length][newMat[0].length];
        for (int i = 0; i < newMat.length; i++) {
            int n = 0;
            for (int j = newMat[0].length - 1; j >= 0; j--) {
                finMat[i][n] = newMat[i][j];
                n++;
            }
        }

        return finMat;

    }
}

1 Comment

Very simple logic to rotate the matrix in clockwise or anticlockwise direction

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.