旋转图像(旋转矩阵)

原题链接

旋转图像备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/rotate-image/

算法分析

        若矩阵的行列数为N,设i表示行索引,i属于[1,N],按照题意旋转矩阵则可以理解为我们需要将第i行的所有元素转换为第N-i+1列,如示例1所示,第1行为[1,2,3],旋转后的第1行则变成了第3列,第2行与第3行同样如此。

图(1)
图(2)

        PS:经现有测试该方法适用于行列数相同的矩阵,但不确定是否适用于行列数不同的矩阵。

        如图(1)索引分别为(0,0),(0,1),(0,2),(0,3),(1,3),(2,3),(3,3),(3,2),(3,1),(3,0),(2,0),(1,0)的点围成了一个圈,假设我们称之为矩阵圈。那么由外向内我们依次称为第1层矩阵圈,第2层矩阵圈,……第n层矩阵圈。图(1)所示有两个矩阵圈,第1层矩阵圈的索引集合为[(0,0),(0,1),(0,2),(0,3),(1,3),(2,3),(3,3),(3,2),(3,1),(3,0),(2,0),(1,0)],第2层矩阵圈的索引集合为[(1,1),(1,2),(2,2),(2,1)]。

        如图(1)和图(2)我们可以发现通过对每个矩阵圈的旋转即可完成对整个矩阵的旋转,而对矩阵圈的旋转实际上就是对矩阵圈进行点交换。点交换的意思是交换矩阵圈四个边上的点,并且每个点是相互对应的。

        如图(3)所示,第一次交换索引为(0,0)和索引为(0,3)的点,第二次交换索引为(0,0)和索引为(3,3)的点,第三次交换索引为(0,0)和索引为(3,0)的点,我们把这称为矩阵圈的点交换。而这仅仅是矩阵圈的第一次点交换,假设该矩阵圈的行数和列数均为m,那么旋转该矩阵圈则需要(m-1)次点交换。

图(3)
图(4)
图(5)
图(6)

        图(3)(4)(5)(6)则为该矩阵圈的一次完整的90°旋转。

        为了从定量角度分析这个规律。首先我们可以定义四个变量rowA,rowB,colA,colB分别表示每一个矩阵圈的首行尾行以及首列尾列,并对它们进行初始化,rowA=0,rowB=m-1,colA=0,colB=m-1,rowA指向当前矩阵圈第一行,rowB指向最后一行,colA指向当前矩阵圈第一列,colB指向最后一列。其次我们再定义一个变量count,表示当前矩阵圈需要进行点交换的次数,count属于[1,m-1]。那么该矩阵圈进行点交换的四个点的索引分别为:

(rowA,colA+count-1),  (rowA+count-1,colB),

(rowB,colB-count+1),  (rowB-count+1,colA)

        我们只需要按照(rowA+count-1,colB),(rowB,colB-count+1),(rowB-count+1,colA)的索引顺序分别与索引为(rowA,colA+count-1)的点进行交换即可,每完成一次点交换则count进行+1操作,当count等于m-1时表示该矩阵圈的90°旋转完成。所以接下来需要收缩rowA,rowB,colA,colB四个变量,从而指向下一层矩阵圈,收缩操作即对rowA和colA进行+1操作,对rowB和colB进行-1操作,重复上述过程从外向内旋转矩阵圈直至rowA、rowB、colA、colB四个变量的值相等则表明整个矩阵完成了90°的旋转。

代码示例(C#) 
public void Rotate(int[][] matrix)
{//定义变量int rowA = 0, rowB = matrix.Length - 1, colA = 0, colB = matrix[0].Length - 1, count = 1;//逻辑主体while (count <= colB - colA){//矩阵点交换(matrix[rowA][colA + count - 1], matrix[rowA + count - 1][colB]) = (matrix[rowA + count - 1][colB], matrix[rowA][colA + count - 1]);(matrix[rowA][colA + count - 1], matrix[rowB][colB - count + 1]) = (matrix[rowB][colB - count + 1], matrix[rowA][colA + count - 1]);(matrix[rowA][colA + count - 1], matrix[rowB - count + 1][colA]) = (matrix[rowB - count + 1][colA], matrix[rowA][colA + count - 1]);//矩阵圈收缩if (count == colB - colA){colA++;colB--;rowA++;rowB--;count = 1;}else count++;}
}
算法解说 

        结合算法分析过程,我们将矩阵的旋转转换为矩阵圈的旋转,然后将矩阵圈的旋转转换为矩阵点的交换,也就是说矩阵旋转的本质就是矩阵中各个元素的交换,实际上我们从图(1)和图(2)就可以发现,转换前的矩阵的第一行变成了转换后的矩阵的最后一列,但是本文的解题思路并未采取这种方式。

       由于每个矩阵圈都有四条边,所以旋转矩阵圈就是在交换四个边上指定的元素,具体的思路算法分析中已经描述得比较详尽,对于如何将分析过程转换为代码,对于多数算法题来说本质上都是明确两个重点,一个是变量,一个是逻辑主体。本题中所用到的变量包括用于明确当前矩阵圈的四个指针,还有一个用于记录当前矩阵圈进行点交换的次数。而逻辑主体则包括矩阵点交换和矩阵圈收缩,同时需要明确逻辑主体退出的条件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/35651.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win10中Docker安装、构建镜像、创建容器、Vscode连接实例

Docker方便一键构建项目所需的运行环境&#xff1a;首先构建镜像(Image)。然后镜像实例化成为容器(Container)&#xff0c;构成项目的运行环境。最后Vscode连接容器&#xff0c;方便我们在本地进行开发。下面以一个简单的例子介绍在win10中实现&#xff1a;Docker安装、构建镜像…

Flutter BottomSheet 三段式拖拽

BottomSheetBehavior 追踪 BottomSheet系统默认实现效果准备要实现的功能点&#xff1a;定义三段式状态&#xff1a;BottomSheetBehavoir阀值定义1. 未达到滚动阀值&#xff0c;恢复状态2. 达到滚动阀值&#xff0c;更新状态 前面倒是有讲过Android原生的BottomSheetBehavior&a…

Flask 框架集成Bootstrap

前面学习了 Flask 框架的基本用法&#xff0c;以及模板引擎 Jinja2&#xff0c;按理说可以开始自己的 Web 之旅了&#xff0c;不过在启程之前&#xff0c;还有个重要的武器需要了解一下&#xff0c;就是著名的 Bootstrap 框架和 Flask 的结合&#xff0c;这将大大提高开发 Web …

国产数据库-内核特性-低基数全局字典

国产数据库-内核特性-StarRocks低基数全局字典 StarRocks2.0引入了低基数全局字典&#xff0c;可以通过全局字典将字符串的相关操作转换成整型相关操作&#xff0c;大大提升查询性能。 1、低基数字典 对于利用整型替代字符串进行处理&#xff0c;通常使用字典编码进行优化。Sta…

人大金仓助力某大型金融机构业务系统异地容灾优化升级

日前&#xff0c;人大金仓助力某大型金融机构应收账款融资服务平台异地容灾项目顺利上线&#xff0c;保证了平台系统运行的连续性和数据安全&#xff0c;为充分发挥平台的融资功能&#xff0c;缓解中小微企业融资难提供了强有力的保障。 “ 缓解中小微企业融资难 某大型金融机构…

【MySQL--->数据库操作】

文章目录 [TOC](文章目录) 一、操作语句1.增2.删3.改4.查5.备份 二、字符集与校验规则 一、操作语句 1.增 语句格式:create database [if no exists]数据库名[create_specification [,create_specification] …]; 中括号内是可选项,if no exists是指如果数据库不存在就创建,存…

STM32 F103C8T6学习笔记7:双机无线串口通信

今日尝试配通俩个C8T6单片机之间的无线串口通信&#xff0c;文章提供原理&#xff0c;源码&#xff0c;测试效果图&#xff0c;测试工程下载&#xff1a; 目录 传输不规范问题&#xff1a; 串口通信资源&#xff1a; 单个串口资源理解&#xff1a; 单片机串口资源&#xf…

Redis的单线程与多线程

Redis的核心处理逻辑一直都是单线程 有一些分支模块是多线程(某些异步流程从4.0开始用的多线程&#xff0c;例如UNLINK、FLUSHALL ASYNC、FLUSHDB ASYNC等非阻塞的删除操作。网络I/O解包从6.0开始用的是多线程;) 为什么是单线程 多线程多好啊可以利用多核优势 官方给的解释 …

UI自动化环境的搭建(python+pycharm+selenium+chrome)

最近在做一些UI自动化的项目&#xff0c;为此从环境搭建来从0到1&#xff0c;希望能够帮助到你&#xff0c;同时也是自我的梳理。将按照如下进行开展&#xff1a; 1、python的下载、安装&#xff0c;python环境变量的配置。 2、pycharm开发工具的下载安装。 3、selenium的安装。…

Leetcode34 在排序数组中查找元素的第一个和最后一个位置

给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。 代码&#xff1a; c…

如何使用 Go 获取 URL 的参数,以及使用时的问题

Go 获取 URL 参数也很容易&#xff0c;但是由于 Go 有严格的数据类型和错误管理&#xff0c;所以在使用时会些微有些复杂。所以本文不仅会讲如何获取 URL 的参数&#xff0c;也会讲在使用时的一些问题。 首先假设 URL 是https://www.example.com/?keywordabc&id12。 其他…

java中函数式接口、Stream流、方法引用、junit单元测试、反射、注解

函数式接口&#xff1a; 在java中有且仅有一个抽象方法的接口称为函数式接口&#xff0c;但是可以包含其它的默认的或静态的方法。 格式&#xff1a; 修饰符 interface 接口名称 {public abstract 返回值类型 方法名称(可选参数);// 其他非抽象方法 }函数式接口&#xff1a;…

服务器安全维护注意事项有哪些?

服务器的安全关系着公司整个网络以及所有数据的安全&#xff0c;我们该如何做好服务器后续的安全维护呢?河南亿恩科技股份有限公司&#xff0c;专注服务器托管23年&#xff0c;不仅是国内专业的互联网基础应用服务提供商之一&#xff0c;还是国家工信部认定的综合电信服务运营…

OpenJDK Maven 编译出错: package jdk.nashorn.internal.runtime.logging does not exist

前言 OpenJDK 1.8.0Maven 3.8.5TencentOS Server 3.1 错误信息 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project tour-common: Compilation failure: Compilation failure: [ERROR] /opt/tour-c…

JavaScript预编译机制

变量预编译 任何变量&#xff0c;如果未经声明就赋值&#xff0c;此变量是属于 window 的属性&#xff0c;而且不会做变量提升&#xff0c;无论在哪个作用域内赋值。比如说直接写 console.log(a)肯定会报错&#xff0c;提示找不到 a。但如果直接写 a 100就不会报错&#xff0…

【Linux命令行与Shell脚本编程】第十九章 正则表达式

Linux命令行与Shell脚本编程 第十九章 正则表达式 文章目录 Linux命令行与Shell脚本编程 第十九章 正则表达式九.正则表达式9.1.正则表达式基础9.1.1.正则表达式的类型9.2.定义BRE模式9.2.1.普通文本9.2.2.特殊字符 9.2.3.锚点字符锚定行首^锚定行尾$组合锚点 9.2.4.点号字符\.…

funbox3靶场渗透笔记

funbox3靶场渗透笔记 靶机地址 https://download.vulnhub.com/funbox/Funbox3.ova 信息收集 fscan找主机ip192.168.177.199 .\fscan64.exe -h 192.168.177.0/24___ _/ _ \ ___ ___ _ __ __ _ ___| | __/ /_\/____/ __|/ __| __/ _ |/ …

SpringBoot复习(39)Servlet容器的自动配置原理

Servlet容器自动配置类为ServletWebServerFactoryAutoConfiguration 可以看到通过Import注解导入了三个配置类&#xff1a; 通过这个这三个配置类可以看出&#xff0c;它们都使用了ConditionalOnClass注解&#xff0c;当类路径存在tomcat相关的类时&#xff0c;会配置一个T…

【数据结构•堆】序列和的前n小元素

题目描述 问题&#xff1a;序列和的前n小元素   给出两个长度为n的有序表A和B, 在A和B中各任取一个, 可以得到 n^2 个和. 求这些和最小的n个。 输入输出格式 输入格式&#xff1a; 输入数据共三行。   第一行&#xff0c;一个整数值n &#xff08; n < 10^4 &#xff…

Linux系列:从0到1用Docker部署springboot项目

目录 1.前提条件 2.编写DockerFile镜像文件 3.打包SpringBoot项目 4.通过软件Xftp进行传输&#xff08;*&#xff09; 1.点击“文件-新建”​编辑 5.操作远程主机 1.docker构建 2.容器运行 6.容器的关闭和删除 1.前提条件 Linux、docker、xftp的安装、一台可以访问的远…