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

旋转图像

旋转图像

思路:

第一意识是找一个数学规律,一个公式可以找到对应的位置。

唉 想不出 没啥思路 看题解了。

一看就懂了  规律就是。。。。。。:原来第 行第 列的元素 在旋转后  会在第 行倒数第i列。

这种题目做少了,多做几个矩阵的总结一下规律就懂了。

法一:这是利用辅助矩阵的方法。

class Solution {
public:void rotate(vector<vector<int>>& matrix) {int n = matrix.size();// C++ 这里的 = 拷贝是值拷贝,会得到一个新的数组auto matrix_new = matrix;for(int i=0;i<n;i++){for(int j=0;j<n;j++){//翻转后矩阵的[i][j]是之前的[n-1-j][i]matrix_new[i][j]=matrix[n-1-j][i];}}matrix=matrix_new;//再来一次值拷贝}
};

法二:不使用辅助数组,原地进行操作,故需要考虑覆盖问题。

为什么要这么想呢,可以从n=2,3看看,可以发现旋转都是很有规律的!!!

法二是利用一个关键公式进行推导:

  matrix_new[j][n - i - 1] = matrix[i][j];

这个公式的意思是,原来[i][j]位置的元素 要旋转到[j][n-i-1]

这个时候[j][n-i-1]就要被覆盖了,我们继续看看这个位置的值旋转后要去哪。

继续代入关键公式,即令i=j,j=n-i-1  我们可以得到[j][n-i-1] 要旋转到[n-i-1][n-j-1]的位置、

我们继续看[n-i-1][n-j-1]要旋转到哪里: 令i=n-i-1,j=n-j-1,我们可以得到[n-i-1][n-j-1]要旋转到

[n-j-1][i]的位置。继续看 ,同理,[n-j-1][i]要旋转到[i][j]

可以大声喊我艹了。我们惊奇的发现闭环了,也就是[i][j]旋转到[j][n-i-1],[j][n-i-1]旋转到[n-i-1][n-j-1],[n-i-1][n-j-1]旋转到[n-j-1][i],[n-j-1][i]又旋转到[i][j],形成了闭环!!

这个时候,我们每次遍历处理四个元素就可以了,处理这四个元素的时候,存一下[i][j],即temp=[i][j],就可以对后续都进行原地赋值操作。即以下五行代码:

temp=[i][j];

[i][j]=[n-j-1][i];

[n-j-1][i]=[n-i-1][n-j-1];

[n-i-1][n-j-1]=[j][n-i-1];

[j][n-i-1]=temp;

每一次处理四个元素,总共有n*n个元素。        

然后剩下的问题是如何确定遍历的范围:

  • 因为每次遍历都是操作4个点,显然我们只需遍历n*n/4个格子即可.
  • 直觉上n*n/4可以等于 (n/2) * (n/2) (即0 <= i < n/2 ,0 <= j < (n/2)),
  • 但也可以等于n * (n/4),究竟是哪种呢?
  • 可以自己模拟一下n=2  n=3就明白了。肯定是前者。
  • n为偶数的时候是四等分:
  • n为奇数时:
  • 综上,不管n是奇数还是偶数,遍历的范围都可以表示为0 <= i < n/2 ,0 <= j < ( 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 temp=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;}}}
};

法三:一些巧妙的方法:用翻转代替旋转

用两次翻转代替旋转:

为什么呢?

我们也分别列出沿水平翻转和沿主对角线翻转的公式:

沿水平翻转:matrix_new[n-i-1][j]=matrix[i][j]

沿对角线翻转:matrix_new[j][i]=matrix[i][j]

这两个联立,可以得到。可以得到matrix_new[j][n-i-1]=matrix[i][j] 而这个就是之前说到的关键公式。所以两次翻转就等于将图像顺时针旋转 90 度。

而这种翻转,直接用swap就好了。

代码:

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;j++){swap(matrix[i][j],matrix[n-i-1][j]);}}for(int i=0;i<n;i++)//对角线翻转{for(int j=0;j<i;j++){swap(matrix[i][j],matrix[j][i]);}}}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Linux驱动开发—平台总线模型详解
  • 【多线程-从零开始-捌】阻塞队列,消费者生产者模型
  • Unity Android端截图保存并获取展示
  • Milvus向量数据库的简介以及用途
  • 怎么判断张量的维度(形状(shape)),即如何定义行数、列数和深度的?
  • ARM 架构硬件新趋势:嵌入式领域的未来
  • 【C#语音文字互转】.NET的TTS文本转语音合成
  • Java面试篇(线程池相关专题)
  • 问题解决:CUDA_HOME environment variable is not set.
  • HTTPS链接建立的过程
  • 工业除尘的一些方法
  • 简要:JVM底层原理、JVM各类垃圾收集器的使用及核心参数的调优、JVM 调优
  • Makefile自动依赖
  • package.json的 和 的区别,以及|| 和 | 的区别
  • 告别杂音,从 AI 音频降噪开始
  • 网络传输文件的问题
  • .pyc 想到的一些问题
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • Computed property XXX was assigned to but it has no setter
  • create-react-app项目添加less配置
  • eclipse的离线汉化
  • Javascript Math对象和Date对象常用方法详解
  • Java面向对象及其三大特征
  • js写一个简单的选项卡
  • mysql innodb 索引使用指南
  • Python_网络编程
  • use Google search engine
  • 浮现式设计
  • ------- 计算机网络基础
  • 容器服务kubernetes弹性伸缩高级用法
  • 深度学习在携程攻略社区的应用
  • 小程序01:wepy框架整合iview webapp UI
  • 运行时添加log4j2的appender
  • 回归生活:清理微信公众号
  • 容器镜像
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​Spring Boot 分片上传文件
  • # Maven错误Error executing Maven
  • # 飞书APP集成平台-数字化落地
  • #每日一题合集#牛客JZ23-JZ33
  • (~_~)
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (六)vue-router+UI组件库
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (十一)图像的罗伯特梯度锐化
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)为C# Windows服务添加安装程序
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .NET 8.0 发布到 IIS
  • .NET C# 操作Neo4j图数据库