【LeetCode-中等】48. 旋转图像(图文详解)

题目

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

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


题目地址:https://leetcode.cn/problems/rotate-image
【LeetCode-中等】48. 旋转图像(图文详解)_第1张图片

方法1:借用辅助数组

作者:本人

刚拿到这题,看到“原地”就不敢动了,只想着谁和谁交换,想了一会儿想不出来。

观察示例1,发现了规律:输入【【1,2,3】,【4,5,6】,【7,8,9】】

只需要输出【【7,4,1】,【8,5,2】,【9,6,3】】即可

输出的二维数组的第一个一维数组的元素 取自 输入的二维数组的每个一维数组的第一个元素,依次循环取即可,也就是“外层(二维数组)从后往前遍历,内层(一维数组)从前往后遍历”

我现将输入数组的全素按上面的规律取出来放到一个数组中存储,再赋值给这个数组,因为题目要求原地,所以最后题目要检查的数组就是matrix数组

class Solution {
    public void rotate(int[][] matrix) {
        int len = matrix.length;
        int arr[] = new int[len*len];
        int temp = 0;
        //将二维数组按规律存储到arr[]中
        for (int j = 0; j < len; j++) {
            for (int i = len - 1; i >= 0; i--) {
                arr[temp] = matrix[i][j];
                temp++;
            }
        }
        temp = 0;
        //再循环赋值给matrix
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len; j++) {
                matrix[i][j] = arr[temp];
                temp++;
            }
        }
    }
}

效果

【LeetCode-中等】48. 旋转图像(图文详解)_第2张图片

可能我的方法时投机取巧吧,因为题目说了原地,但我还是建立了一个存储的数组,但通过还是能通过,如果这个方法真的可以算一种合理的解法,那这道题的难度我觉得应该是“简单”,而不是“中等” ,但我看力扣官方题解竟然也有类似解法,emm......

所以推荐读者看下面的解法,真正做到了“原地”。

方法2:两次翻转法

作者:本人

思路

观察示例1我们能得出规律

原数组长这样
1 2 3  
4 5 6  
7 8 9  
左右翻转之后长这样
3 2 1  
6 5 4  
9 8 7  
对角线翻转之后长这样
7 4 1  
8 5 2  
9 6 3  

所以我们的方法就是

1.先二维数组左右翻转

2.再沿 左下到右上的 对角线翻转

思路非常简单,但代码不好写

先写一个交换的代码

    //将arr[a] 与 brr[b] 交换
    private void swap(int[] arr, int a,int[] brr , int b) {
        int temp = arr[a];
        arr[a] = brr[b];
        brr[b] = temp;
    }

左右翻转

1. 交换第一个数组的 最左边元素 和 最右边元素

2. 交换第一个数组的 左边第二个元素 和 右边第二个元素

3. 循环交换到 左边>=右边

4. 开始交换 第二个数组的最左边元素 和 最右边元素

5. 循环交换到 左边>=右边

6.开始交换 第三个数组的最左边元素 和 最右边元素

7. 循环交换到 左边>=右边

        //左右翻转
        for (int i = 0; i < len; i++) {
            int left = 0;
            int right = len-1;
            while (left < right){
                swap(matrix[i] ,left ,matrix[i] ,right);
                left++;
                right--;
            }
        }

左下到右上的对角线翻转

先定义tempI 和 tempJ,指向左下角的元素

交换对应颜色的数组

【LeetCode-中等】48. 旋转图像(图文详解)_第3张图片

 将两个指针沿对角线移动,再交换对应颜色的元素

【LeetCode-中等】48. 旋转图像(图文详解)_第4张图片

 最后,两指针移动到对角线顶部就交换完毕了

注意

思路虽然简单,但自己写代码就需要多思考,建议自己写一写这一块

        //沿 左下到右上 对角线翻转
        int tempI = len-1;
        int tempJ = 0;
        while (tempI > 0){
            int i = tempI;
            int j = tempJ;
            while (i > 0){
                swap(matrix[i-1],tempJ,matrix[tempI], j+1);
                i--;
                j++;
            }
            tempI--;
            tempJ++;
        }

完整代码

/**
 * 两次翻转法:
 * 1.先左右翻转 
 * 2.再沿 左下到右上的 对角线翻转
 */
class Solution {
    public  void rotate(int[][] matrix) {
        int len = matrix.length;
        //左右翻转
        for (int i = 0; i < len; i++) {
            int left = 0;
            int right = len-1;
            while (left < right){
                swap(matrix[i] ,left ,matrix[i] ,right);
                left++;
                right--;
            }
        }
        //沿 左下到右上 对角线翻转
        int tempI = len-1;
        int tempJ = 0;
        while (tempI > 0){
            int i = tempI;
            int j = tempJ;
            while (i > 0){
                swap(matrix[i-1],tempJ,matrix[tempI], j+1);
                i--;
                j++;
            }
            tempI--;
            tempJ++;
        }
    }
    //将arr[a] 与 brr[b] 交换
    private void swap(int[] arr, int a,int[] brr , int b) {
        int temp = arr[a];
        arr[a] = brr[b];
        brr[b] = temp;
    }
}

效果

【LeetCode-中等】48. 旋转图像(图文详解)_第5张图片

这个方法可能更符合出题人的想法,真正的是原地修改。 

你可能感兴趣的:(LeetCode,1024程序员节,leetcode,算法)