LeetCode-探索-初级-数组-旋转图像-java

旋转图像

给定一个 × n 的二维矩阵表示一个图像。

将图像顺时针旋转 90 度。

说明:

你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

示例 1:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]

示例 2:

给定 matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

原地旋转输入矩阵,使其变为:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

思路简单:

考察如下矩阵

a[0][0] a[0][1] a[0][2] a[0][3]

a[1][0] a[1][1] a[1][2] a[1][3]

a[2][0] a[2][1] a[2][2] a[2][3]

a[3][0] a[3][1] a[3][2] a[3][3]

将a[0][0]元素相关的元素旋转之后可以得到

a[3][0] a[0][1] a[0][2] a[0][0]

a[1][0] a[1][1] a[1][2] a[1][3]

a[2][0] a[2][1] a[2][2] a[2][3]

a[3][3] a[3][1] a[3][2] a[0][3]

容易发现,元素a[m][n]经过旋转的坐标是a[n][a.length - m - 1];

我们已经发现单个元素旋转的代码,接下来只需要寻找一共有多少组元素需要进行旋转即可。(四个一组)

还是考察上面的矩阵,我们很容易就能发现

a[3][0] a[0][1] a[0][2] a[0][0]

a[1][0] a[1][1] a[1][2] a[1][3]

a[2][0] a[2][1] a[2][2] a[2][3]

a[3][3] a[3][1] a[3][2] a[0][3]

只需要将加粗的元素所在的一组元素进行旋转,就可以旋转整个矩阵。由此,我们可以写出如下代码:

public void rotate(int[][] matrix) {
        int last = 0;  //last element be replaced
        int next = 0;  //next element to be replaced
        int nextRow = 0;
        int nextCol = 0;
        for (int row = 0 ; row < matrix.length / 2 ; row ++) {
            for (int col = row ; col < matrix.length - 1 - row ; col ++) {
                last = matrix[row][col];
                for (int i = 0 ; i < 4 ; i ++) {
                    nextRow = col;
                    nextCol = matrix.length - row - 1;
                    next = matrix[nextRow][nextCol];
                    matrix[nextRow][nextCol] = last;
                    last = next;
                    row = nextRow;
                    col = nextCol;
                }
            }
        }
    }

官网上给出的最佳解法:

说实话,官网上的方法非常有创造性。

(别说什么方法上的局限性,再局限性的方法,自己想不到,就是自己菜,没有什么理由解释)

也是被官网又一次成功实现了智商压制

接下来是解题思路,以一个3*3的矩阵为例:

a[0][0] a[0][1] a[0][2]

a[1][0] a[1][1] a[1][2]

a[2][0] a[2][1] a[2][2]

先进行一次转置

a[0][0] a[1][0] a[2][0]

a[0][1] a[1][1] a[2][1]

a[0][2] a[1][2] a[2][2]

再左右对称一下

a[2][0] a[1][0] a[0][0]

a[2][1] a[1][1] a[0][1]

a[2][2] a[1][2] a[0][2]

然后旋转90°就转完了

代码如下:

/**
     * This is leetcode standardized answer
     * The method use two symmetries to implement the function
     * @param matrix
     */
    public void rotate0(int[][] matrix) {
        if (matrix.length == 1)
            return ;
        //first symmetry
        int temp = 0;
        for (int row = 0 ; row < matrix.length ; row ++)
            for (int col = row + 1 ; col < matrix.length ; col ++) {
                temp = matrix[row][col];
                matrix[row][col] = matrix[col][row];
                matrix[col][row] = temp;
            }
            //end loop

        //second symmetry
        int limit = matrix.length / 2;
        int symmetryCol = 0;
        for (int row = 0 ; row < matrix.length ; row ++)
            for (int col = 0 ; col < limit ; col ++) {
                symmetryCol = matrix.length - 1 - col;
                temp = matrix[row][col];
                matrix[row][col] = matrix[row][symmetryCol];
                matrix[row][symmetryCol] = temp;
            }
    }

猜你喜欢

转载自blog.csdn.net/jdie00/article/details/85451457