package com.fishercoder.solutions; import com.fishercoder.common.utils.CommonUtils; public class _48 { /** * Note: this is an n*n matrix, in other words, it's a square, this makes it easier as well. */ public static class Solution1 { //Time: O(n^2) //Space: O(1) public void rotate(int[][] matrix) { /**First swap the elements on the diagonal, then reverse each row: * 1, 2, 3 1, 4, 7 7, 4, 1 * 4, 5, 6 becomes 2, 5, 8 becomes 8, 5, 2 * 7, 8, 9 3, 6, 9 9, 6, 3 **/ int m = matrix.length; for (int i = 0; i < m; i++) { for (int j = i; j < m; j++) { /**ATTN: j starts from i, so that the diagonal changes with itself, results in no change.*/ int tmp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = tmp; } } CommonUtils.print2DIntArray(matrix); /**then reverse*/ for (int i = 0; i < m; i++) { int left = 0; int right = m - 1; while (left < right) { int tmp = matrix[i][left]; matrix[i][left] = matrix[i][right]; matrix[i][right] = tmp; left++; right--; } } } } public static class Solution2 { /** * First swap the rows bottom up, then swap the element on the diagonal: * <p> * 1, 2, 3 7, 8, 9 7, 4, 1 * 4, 5, 6 becomes 4, 5, 6 becomes 8, 5, 2 * 7, 8, 9 1, 2, 3 9, 6, 3 * <p> * Time: O(n^2) * Space: O(1) */ public void rotate(int[][] matrix) { int m = matrix.length; int n = matrix[0].length; int top = 0; int bottom = n - 1; while (top < bottom) { int[] tmp = matrix[top]; matrix[top] = matrix[bottom]; matrix[bottom] = tmp; top++; bottom--; } for (int i = 0; i < m; i++) { for (int j = i + 1; j < n; j++) { int tmp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = tmp; } } } } public static class Solution3 { /** * You only need to rotate the top right quarter, * with this example: * {1, 2, 3, 4}, * {5, 6, 7, 8}, * {9, 10, 11, 12}, * {13, 14, 15, 16} * * top will only be: * 1, 2, 3, * 6 * * then this entire matrix is rotated. As they'll drive to ratate the corresponding three elements in the matrix. * * Another cool trick that this solution takes advantage is that because it's a square matrix, * meaning number of rows equals to the number of columns, we could do swap like this, * if it's a rectangular, below method won't work and will throw ArrayIndexOutOfBoundsException. * */ public void rotate(int[][] matrix) { int n = matrix.length; for (int i = 0; i < n / 2; i++) { for (int j = i; j < n - i - 1; j++) { //save the top left int top = matrix[i][j]; System.out.println("top = " + top); //move bottom left to top left matrix[i][j] = matrix[n - 1 - j][i]; //move bottom right to bottom left matrix[n - 1 - j][i] = matrix[n - i - 1][n - 1 - j]; //move top right to bottom right matrix[n - i - 1][n - 1 - j] = matrix[j][n - i - 1]; //move top left to top right matrix[j][n - i - 1] = top; } } } } }