LeetCode 48旋转图像

175 阅读2分钟

「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」。

题目:给定一个二维数组,将此二维数组按顺时针旋转90度,必须原地旋转,不可使用额外数组。详细题目可看此处

解题思路

最开始的想法就是新建一个辅助数组,依次遍历原数组中的内容,将原数组内容按规律填入辅助数组,之后将辅助数组的值复制给原数组即可,代码如下:

public void rotate(int[][] matrix) {
        int n = matrix.length;
        int[][] help = new int[n][n];
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                help[j][n-i-1] = matrix[i][j];
            }
        }

        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                matrix[i][j] = help[i][j];
            }
        }
    }

该方法的时间复杂度和空间复杂度都是O(N2)O(N^2),并且完成了击败百分百的Java提交用户,但本题的一个要求是不可使用额外数组,此处使用了一个和原数组等大的辅助数组,因此需要考虑新的方法。本题倾向于找规律,对于一个二维矩阵,要将数组旋转,其最重要的是如何交换数组中元素。观察需要得到的结果数组可以发现最终的结果有点类似于矩阵的转置,将矩阵转置后其结果和最终结果对称,此时只需要将数组进行左右镜像即可,代码如下:

public void rotate(int[][] matrix) {
        for(int i=0;i<matrix.length;i++){
            for(int j=0;j<i;j++){
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
        int left=0,right=matrix.length-1;
        while (left<right){
            for(int i=0;i<matrix.length;i++){
                int temp=matrix[i][left];
                matrix[i][left] = matrix[i][right];
                matrix[i][right] = temp;
            }
            left++;
            right--;
        }
    }

上述代码最终运行时间0ms,击败了百分百的Java提交用户,算法的时间复杂度为O(N2)O(N^2),空间复杂度为O(1)O(1)。类似本题的推广还有将数组顺时针旋转180度,将数组下顺时针旋转270度等,这类题目的思路和本题思路一致,所不同的地方在于子过程的顺序不同,不同的顺序可以得到 不同的结果,例如对于顺时针旋转180度,此时只需要将数组先上下镜像再左右镜像即可。对于顺时针旋转270度,此时将数组先转置之后进行上下镜像即可。