『LeetCode|每日一题』---->旋转矩阵

目录

每日一句

作者简介

 『LeetCode|每日一题』旋转矩阵

1.每日一题

2.解题思路(新数组法)

        2.1 思路分析

        2.2 核心代码

        2.3 完整代码

        2.4 运行情况

 3.解题思路(原地旋转)

        3.1 思路分析

        3.2 核心代码 

        3.3 完整代码

        3.4 运行结果


每日一句

把烦心事都抛掉,腾出地方让鲜花盛开

作者简介

🏡个人主页:XiaoChen_Android 

📚学习专栏:力扣专栏

🕒发布日期:2022/9/6

在这里插入图片描述

 『LeetCode|每日一题』旋转矩阵

1.每日一题

原文链接--->点我

2.解题思路(新数组法)

        2.1 思路分析

首先看到这个题,我就在草稿纸上自己一步一步去旋转,最后试了几次之后也发现了一个规律

        S1:首先第一步定义一个新的矩阵,用来存储旋转后的数组;

        S2:然后一行一行看,首先第一行就反转到了最后一列,第二行就反转到了倒数第二列,以此类推;

        S3:新建的数组都初始化之后,就得到了我们想要的反转数组;

        S4:最后把反转数组覆盖原数组即可

此方法的时间和空间复杂度都是O(n^{2}),很显然不是最优的方法

        2.2 核心代码

        for(int i = 0 ; i < row ; i++){
            for(int j = 0 ; j < col ; j++){
                nums[j][col - i - 1] = matrix[i][j];
            }
        }
        for(int i = 0 ; i < row ; i++){
            for(int j = 0 ; j < col ; j++){
                matrix[i][j] = nums[i][j];
            }
        }

        2.3 完整代码

class Solution {
    public void rotate(int[][] matrix) {
        int row = matrix.length;
        int col = matrix[0].length;
        int[][] nums = new int[row][col];
        for(int i = 0 ; i < row ; i++){
            for(int j = 0 ; j < col ; j++){
                nums[j][col - i - 1] = matrix[i][j];
            }
        }
        for(int i = 0 ; i < row ; i++){
            for(int j = 0 ; j < col ; j++){
                matrix[i][j] = nums[i][j];
            }
        }
    }
}

        2.4 运行情况

 3.解题思路(原地旋转)

        3.1 思路分析

首先旋转的思路和上一个方法相同,但是此方法是在原数组上旋转

有的读者会有疑问,原地旋转岂不是把后面的数据覆盖了吗,其实解决这个问题很简单,我们定义一个flag来存储之前的值,这样就不会被覆盖了

最关键的地方就在于旋转之后的值会去哪里呢?

        S1:flag = matrix[col][n - row - 1],matrix[col][n - row - 1] = matrix[row][col];

        S2:matrix[col][n - row - 1]旋转之后去哪了呢?我们还是使用关键的等式,row = col,col = n - row - 1,代入之后可以得到matrix[n − row − 1][n − col − 1] = matrix[col][n − row − 1];

        S3:同样的,直接覆盖还是会覆盖掉之前的值,因此还是需要一个临时变量来存储该值,不过这次不需要重新定义,直接用上一个就好了,此时:flag = matrix[n − row − 1][n − col − 1],matrix[n − row − 1][n − col − 1] = matrix[col][n − row − 1],matrix[col][n − row − 1] = matrix[row][col];

        S4:再经过同样的步骤,matrix[n − row − 1][n − col − 1]旋转之后会去哪呢?此时可以通过等式row = n - row - 1,col = n - col - 1带入得到matrix[n − col − 1][row]=matrix[n − row − 1][n − col − 1],同样用临时变量来存储之前的值,flag = matrix[n − col − 1][row],matrix[n − col − 1][row] = matrix[n − row − 1][n − col − 1],matrix[n − row − 1][n − col − 1] = matrix[col][n − row − 1],matrix[col][n − row − 1] = matrix[row][col];

        S5:那么此时matrix[n − col − 1][row]旋转之后回到了哪里呢?通过等式row = n - col - 1,col = row,代入可得matrix[row][col]=matrix[n−col−1][row],此时同样也是用一个临时变量来存储之前的值,并且此时回到了最初的起点,也就可以发现

matrix[row][col]、matrix[col][n - row - 1]、matrix[n − row − 1][n − col − 1]、matrix[n − col − 1][row]四项处于一个循环之中,每一项旋转之后的位置就是下一项的位置,因此用一个临时变量来完成四个位置的交换

注意:当矩阵的长度为奇数时,那么最中间的那个数是不用旋转的,所以为了保证不重复不遗漏,奇数的时候我们需要枚举(n^{2} - 1) / 4个位置

        3.2 核心代码 

        for (int i = 0; i < n / 2; ++i) {
            for (int j = 0; j < (n + 1) / 2; ++j) {
                int flag = matrix[i][j];
                matrix[i][j] = matrix[n - j - 1][i];
                matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1];
                matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1];
                matrix[j][n - i - 1] = temp;
            }
        }

        3.3 完整代码

class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;
        for (int i = 0; i < n / 2; ++i) {
            for (int j = 0; j < (n + 1) / 2; ++j) {
                int flag = matrix[i][j];
                matrix[i][j] = matrix[n - j - 1][i];
                matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1];
                matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1];
                matrix[j][n - i - 1] = flag;
            }
        }
    }
}

        3.4 运行结果


🍁 类似题目推荐:

1.数据结构基础 

2.算法专项练习 

3.剑指offer专项练习 

4.推荐一个学习网站:LeetCode,算法的提升在于日积月累,只有每天练习才能保持良好的状态

如果文章对各位大佬有帮助就支持一下噢,新手尝试,不好的地方请各位大佬多多指教!  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值