当前位置: 首页 > news >正文

leetcode_48 旋转图像

1. 题意

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

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

2. 题解

2.1 暴力

我们先通过暴力弄明白是怎么转的,顺时针旋转90度;

实际上就是把第一行变成了倒数第一列,第二行变成了倒数第二列。

因此我们可以写出旋转前后的对应关系

matrix[i][j]=new_matrix[j][n−1−i]matrix[i][j] = new\_matrix[j][n-1-i] matrix[i][j]=new_matrix[j][n1i]

用一个新的数组来记录这个新数组,最后再把新数组的值给赋值回来

不就好了吗?

当然这是不符合原地的空间复杂度要求的。

class Solution {
public:void rotate(vector<vector<int>>& matrix) {int n = matrix.size();vector<vector<int>> sup(n, vector<int>(n));for (int r = 0;r < n; ++r ) {for (int c = 0; c < n; ++c) {sup[c][n - r - 1] = matrix[r][c];}}matrix = sup;}
};
2.2 转置+反转

如果学过矩阵的话,会知道有一种操作叫转置,也就是行列之间互换。

第一行变成了第一列,第二行变成了第二列。

但是这跟我们上面的要求还不符?怎么办呢?

我们反转一下不就好了吗?

反转列是典型的相向双指针不用多说。

而对于转置操作,就是行列互换。

at[i][j]=a[j][i]at[i][j] = a[j][i] at[i][j]=a[j][i]

(i,j),(j,i)(i,j),(j,i)(i,j),(j,i)关于r=cr=cr=c对称,

我们只需要枚举所有的i>ji>ji>j或者i<ji<ji<j的点进行交换就可以了。

class Solution {
public:void rotate(vector<vector<int>>& matrix) {int n = matrix.size();for (int i = 0; i < n; ++i) {for (int j = 0; j < i; ++j) {if (i != j) {std::swap(matrix[i][j], matrix[j][i]);}}}for ( int i = 0; i < n; ++i) {int l = 0,r = n - 1;while (l < r) {std::swap(matrix[i][l], matrix[i][r]);l++;r--;}}}
};
2.3 原地旋转

由于有四个方向,每次旋转完后的位置有新的数了。

因此我们需要对于一个位置一直旋转到结束循环为止。

我们假设起始的位置在(i,j)(i,j)(i,j)

上面我们已经知道了它顺时针旋转90度后的位置在(j,n−1−i)(j,n-1-i)(j,n1i)

那这个新位置旋转后在哪里呢?

直接代入上面的情况就行了,新的位置在(n−1−i,n−1−j)(n - 1 -i, n- 1 - j)(n1i,n1j)

继续寻找下一个新位置,下一个新位置在(n−1−j,i)(n - 1 - j, i)(n1j,i)

继续寻找下一个新位置,下一个新位置在(i,j)(i , j)(i,j)

这样就构成了一个loop

(i,j)→(j,n−1−i)→(n−1−i,n−1−j)→(n−1−j,i)→(i,j)(i,j) \to(j,n-1-i) \to (n-1-i, n-1-j) \\ \to(n-1-j,i) \to (i, j) (i,j)(j,n1i)(n1i,n1j)(n1j,i)(i,j)

对于每个变换的位置,我们只需要按上面的顺序处理就可以了。

接下来要做的是找到所有的需要处理的位置,要不重不漏。

首先是偶数的情况,

很显然只需要处理0≤i<n/2,0≤j<n/20\le i < n/2,\ 0 \le j < n/20i<n/2, 0j<n/2的情况就可以了。

在这里插入图片描述

其次是奇数的情况,看下面的图吧。

中间的点我们不需要处理。

对于行来说,0≤i<⌊n/2⌋0 \le i < \lfloor n/2 \rfloor0i<n/2

对于列来说,0≤j≤⌈n/2⌉0 \le j \le \lceil n/2 \rceil0jn/2

在这里插入图片描述

综合两种情况看

0≤i<⌊n/2⌋0≤j<⌊(n+1)/2⌋0 \le i < \lfloor n/2\rfloor\\ 0 \le j < \lfloor (n+1)/2 \rfloor 0i<n/20j<⌊(n+1)/2

这种方法也就是官方的做法了

class Solution {
public:void rotate(vector<vector<int>>& matrix) {int n = matrix.size();for (int i = 0; i < n / 2; ++i) {for (int j = 0; j < (n + 1) / 2; ++j) {int tmp = 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 ] = tmp;}}}
};

另外一种做法是基于层来做旋转,如下图所示.

假设当前层的左端和上端的值为mn

下端和右端的值为mx

对于上端的点(mn,i)(mn, i)(mn,i),它所在的圈层容易求出为

(mn,i)→(i,mx)→(mx,mx−(i−mn))→(mx−(i−mn),mn)→(mn,i)(mn,i) \to(i, mx) \to(mx, mx-(i-mn))\\ \to(mx-(i-mn), mn) \to(mn,i) (mn,i)(i,mx)(mx,mx(imn))(mx(imn),mn)(mn,i)

对于每一层来说, 我们只需要遍历(mn,i),mn≤i<mx(mn,i), mn \le i < mx(mn,i),mni<mx

在一层处理完成后,左右边界往中间收缩,一直处理到mn≥mxmn \ge mxmnmx
在这里插入图片描述

代码

class Solution {
public:void rotate(vector<vector<int>>& matrix) {int n = matrix.size();int mx = n - 1;int mn = 0;while ( mn < mx) {for (int i = mn; i < mx; ++i) {swap(matrix[mn][i], matrix[i][mx]);swap(matrix[mn][i], matrix[mx][mx - (i - mn)]);swap(matrix[mn][i], matrix[mx - (i - mn)][mn]);}++mn;--mx;}}
};

参考

leetcode

http://www.dtcms.com/a/360157.html

相关文章:

  • DAY50打卡
  • Ansible配置文件与主机清单
  • Library cache lock常见案例分析(二)
  • 在Windows的wsl中如何以root登录Ubuntu
  • KMP 算法相关练习题
  • AI 重构内容创作:从文案生成到视频剪辑,创作者该如何与 AI 协同共生?
  • 用产品经理的思维,重构AI时代的增长Playbook
  • CatBoost vs XGBoost:两大Boosting框架的全面对比
  • 【AI智能体】Dify 实现自然语言转SQL操作数据库实战详解
  • 暄桐零基础书法入门课《写字旅行攻略》报名啦
  • 鸿蒙开发入门:ArkTS 运算符与分支循环全解析(含实战案例 + 避坑指南)
  • 常见的两栏布局实现方法
  • P2P技术应用:去中心化
  • Transformer架构三大核心:位置编码(PE)、前馈网络(FFN)和多头注意力(MHA)。
  • Reactor模式--单线程版本
  • HTML5国庆网站源码
  • Unity学习----【数据持久化】二进制存储(二)--文件流
  • 有关指针的认知盲区:指针大小,决定因素,指针变量
  • Nano Banana:下一代AI图像创作与编辑指南
  • [强网杯2019]随便注-----堆叠注入,预编译
  • 主网上线后生态极速扩张的 Berachain 生态,有哪些值得关注的项目?
  • Java全局异常处理器:优雅处理系统异常
  • 【Android】LayoutInflater 控件实例化的桥梁类
  • 【重学MySQL】九十五、Linux 下 MySQL 大小写规则设置详解
  • Java中的异常,枚举,泛型,代理
  • 人工智能知识体系全景图:从基础概念到2025年前沿技术(一)
  • 2025年8月个人工作生活总结
  • vsftpd的基本整理
  • 基于多模态大模型的PCB智能缺陷检测与分析
  • STM32F103C8T6的智能医疗药品存储柜系统设计与华为云实现