当前位置: 首页 > 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.xdnf.cn/news/1411921.html

相关文章:

  • FFMPEG学习任务
  • 第 14 篇:K-Means与聚类思维——当AI在没有“标准答案”的世界里寻宝
  • 【C2000】C2000的硬件设计指导与几点意见
  • 开源知识抽取框架 推荐
  • 京东获取商品评论指南,实时关注用户反馈
  • 官方 API 与网络爬虫的技术特性对比及选型分析
  • Unity学习----【数据持久化】二进制存储(三)--文件夹操作
  • OpenStack 01:介绍
  • 暄桐林曦老师关于静坐常见问题的QA
  • 基于GA遗传优化的双向LSTM融合多头注意力(BiLSTM-MATT)时间序列预测算法matlab仿真
  • windows系统中的docker,xinference直接运行在容器目录和持载在宿主机目录中的区别
  • isat将标签转化为labelme格式后,labelme打不开的解决方案
  • MyBatis 黑马 辅助配置,数据库连接池
  • 柔性数组与不定长数据
  • 【秋招笔试】2025.08.31饿了么秋招笔试题
  • SPMTE 2022概述
  • 线程池常见面试问答
  • 一次解决 Elasticsearch 两大难题: 掌握去重和深分页的最佳实践
  • Day19_【机器学习—线性回归 (1)】
  • PerfectSquares.java
  • c++程序员日常超实用工具(长期记录更新)
  • 疯狂星期四文案网第56天运营日记
  • 创意无界:云渲染如何让视觉创作触手可及
  • python如何下载svg图片
  • 【LeetCode - 每日1题】解数独
  • 虚幻引擎技术开放日!facecar分享3D HMI设计与UE开发经验
  • 基于单片机智能电子秤/称重计费
  • Idea启动错误-java.lang.OutOfMemoryError:内存不足错误。
  • DBeaverEE Mac 数据库管理工具
  • 决胜千里之外:服务器及硬件项目标书制作全流程与避坑指南