Leetcode【二维数组】 | 48.Rotate Image 旋转图像/矩阵

本文介绍了如何解决LeetCode 48题——旋转图像/矩阵,探讨了两种方法:直接原地旋转和翻转代替旋转。在原地旋转方法中,解释了旋转矩阵的思路和过程,以及如何使用一个临时变量实现原地旋转。在翻转代替旋转的方法中,解释了如何通过转置和水平翻转实现90度旋转,并提供了Python实现的简洁代码。
摘要由CSDN通过智能技术生成

题目

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。
不占用额外内存空间能否做到?
示例 1:
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotate-matrix-lcci

解题

  该题的关键有两点: 1)旋转90°怎么做到?2)原地旋转不占用额外空间怎么做到?
  简单来说,矩阵旋转90°其实就是: (“=>” 表示 “旋转至”)
  1、矩阵的第一行 => 最后一列,第二行 => 倒数第二列…,最后一行 => 第一列
  2、矩阵的第一列(从上往下) => 第一行(从右往左,但这是由于行变列翻转导致的,不影响),第二列 => 第二行…
  即matrix[第i行][第j列] => matrix[第j行][第n+1-i列]
  以上我们描述中起始和结束用的是第1行和第n行,开头末尾和为n+1;而在数组中索引是从0到n-1, 头尾和为n-1;所以代码中数组的公式其实是为matrix[i][j] => matrix[j][n-1-i]
  因为不能占用额外内存空间, 所以不能创建另一个数组直接用公式将原数组输入进去

直接原地旋转

思路

 1、通过旋转公式会发现:
 matrix[i][j] => matrix[j][n-1-i] => matrix[ n-1-i][n-1-j] => matrix[n-1-j][i] => matrix[i][j]
 四个元素正好依次旋转到下个位置循环一圈到原点
 比交换(temp=a,a=b,b=temp)更复杂一点,这样的一个循环正好也可以只采用一个临时变量temp, 就完成原地的循环赋值变换:
 temp = matrix[i][j]
 matrix[i][j]=matrix[n-1-j][i]
 matrix[n-1-j][i] = matrix[n-1-i][n-1-j]
 matrix[n-1-i][n-1-j] = matrix[j][n-1-i]
 matrix[j][n-1-i] = temp
 
 2、下一步就是一个矩阵中, 有几个圈 ? 需要枚举几个初始位置正好完成整个矩阵所有元素的旋转, 保证既不重复, 也不遗漏
 因为一个循环有4个元素, 整个矩阵分为四块(左上、右上、右下、左下)整个矩阵有n2个元素, 所以每一块有n2/4个元素进行循环( n为偶数可以直接整除, n为奇数时剩一个不用旋转的中心点)
 将左上=>右上=>右下=>左下=>左上。
 枚举左上的那块子矩阵的所有元素进行上述旋转操作即可。
 左上子矩阵为 n/2 x (n2/4)/(n/2) (这里的“/” 是java中的“/”向下取整) 分为不同情况就是如下方式:
 ① 当n为偶数时,子矩阵为 n/2 x n/2
 ② 当n为奇数时,子矩阵为(n-1)/2 x (n+1)/2
 
 时间复杂度:O(n2)
 空间复杂度:O(1)

代码

//不分奇偶数的写法
class Solution {
   
    public void rotate(int[][] matrix) {
   
        int n = matrix.length;
        if(n == 0||n == 1){
   
            return;
        }
        for(int i = 0; i < n/2; i++){
   
            for(int j = 0; j < (n*n/4)/(n/2); j++){
   
                int temp = matrix[i][j];
                matrix[i][j] = matrix[n-1-j][i];
                matrix
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值