旋转图像-leetcode

news/2025/9/23 21:23:32/文章来源:https://www.cnblogs.com/foxt/p/19108106

题目描述

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

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

示例 1:

img

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

img

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

解法一

思路:

采用辅助数组,一层一层的进行转换,我们读取最外层的一圈数据存入列表中,再将列表中的元素进行后移操作。

代码:

class Solution {public void rotate(int[][] matrix) {int count=(matrix.length+1)/2;int step=0;int n=matrix.length;//方位int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};while(step<count) {List<Integer> numList=new ArrayList<>();int total=4*(n-1);int row=step,col=step;int directionIndex = 0;//读取最外层数据for(int i=0;i<total;i++){//读取数值numList.add(matrix[row][col]);int nextRow = row + directions[directionIndex][0], nextCol = col + directions[directionIndex][1];//出现下列情况就要换方向if (nextRow < step || nextRow >=step+n || nextCol < step || nextCol >=step+n) {directionIndex = (directionIndex + 1) % 4;}row += directions[directionIndex][0];col += directions[directionIndex][1];}int cnt=0;for(int i=numList.size()-n+1;i<numList.size();i++){numList.add(cnt++,numList.get(i));numList.remove(i+1);}row=step;col=step;for(int i=0;i<total;i++){//读取数值matrix[row][col]=numList.get(i);int nextRow = row + directions[directionIndex][0], nextCol = col + directions[directionIndex][1];//出现下列情况就要换方向if (nextRow < step || nextRow >=step+n || nextCol < step || nextCol >=step+n) {directionIndex = (directionIndex + 1) % 4;}row += directions[directionIndex][0];col += directions[directionIndex][1];}step++;n=n-2;numList.clear();} }
}

解法二

思路:

来自官方解答。寻找转换的规律。对于矩阵中的第一行而言,在旋转后,它出现在倒数第一列的位置:

image-20250923210531521

并且,第一行的第 x 个元素在旋转后恰好是倒数第一列的第 x 个元素。

对于矩阵中的第二行而言,在旋转后,它出现在倒数第二列的位置:

image-20250923210549139

对于矩阵中的第三行和第四行同理。这样我们可以得到关键等式

image-20250923210636455

我们观察关键等式

它阻止了我们进行原地旋转,这是因为如果我们直接将matrix[row][col]放到原矩阵中的目标位置 matrix[col][n−row−1]

image-20250923210822904

原矩阵中的 matrix[col][n−row−1] 就被覆盖了!这并不是我们想要的结果。因此我们可以考虑用一个临时变量 temp 暂存 matrix[col][n−row−1] 的值,这样虽然 matrix[col][n−row−1] 被覆盖了,我们还是可以通过 temp 获取它原来的值:

image-20250923210904978

那么 matrix[col][n−row−1] 经过旋转操作之后会到哪个位置呢?我们还是使用方法一中的关键等式,不过这次,我们需要将

image-20250923210929626

带入关键等式,就可以得到:

image-20250923210946707

同样地,直接赋值会覆盖掉 matrix[n−row−1][n−col−1] 原来的值,因此我们还是需要使用一个临时变量进行存储,不过这次,我们可以直接使用之前的临时变量 temp:

image-20250923211019040

我们再重复一次之前的操作,matrix[n−row−1][n−col−1] 经过旋转操作的位置

image-20250923211123655

带入关键等式,就可以得到:

image-20250923211139809

写进去:

image-20250923211156246

matrix[n−col−1][row] 经过旋转操作后的位置:

image-20250923211315422

带入关键等式,就可以得到:

image-20250923211330847

我们回到了最初的起点 matrix[row][col],也就是说:

image-20250923211350291

这四项处于一个循环中,并且每一项旋转后的位置就是下一项所在的位置!因此我们可以使用一个临时变量 temp 完成这四项的原地交换:

image-20250923211410788

当我们知道了如何原地旋转矩阵之后,还有一个重要的问题在于:我们应该枚举哪些位置 (row,col) 进行上述的原地交换操作呢?由于每一次原地交换四个位置,因此

image-20250923211457928

image-20250923211508341

代码:

class Solution {public void rotate(int[][] matrix) {int n = matrix.length;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;}}}
}

解法三

思路:

来自官方解答。采用翻转的思想,顺时针旋转等效于先水平翻转然后对角线翻转。

作为例子,先将其通过水平轴翻转得到:

image-20250923211631388

再根据主对角线翻转得到:

image-20250923211645829

就得到了答案。对于水平轴翻转而言,我们只需要枚举矩阵上半部分的元素,和下半部分的元素进行交换,即

image-20250923211709250

对于主对角线翻转而言,我们只需要枚举对角线左侧的元素,和右侧的元素进行交换,即

image-20250923211725254

将它们联立即可得到:

image-20250923211738382

和方法一、方法二中的关键等式:

image-20250923211752746

是一致的。

代码:

class Solution {public void rotate(int[][] matrix) {int n = matrix.length;// 水平翻转for (int i = 0; i < n / 2; ++i) {for (int j = 0; j < n; ++j) {int temp = matrix[i][j];matrix[i][j] = matrix[n - i - 1][j];matrix[n - i - 1][j] = temp;}}// 主对角线翻转for (int i = 0; i < n; ++i) {for (int j = 0; j < i; ++j) {int temp = matrix[i][j];matrix[i][j] = matrix[j][i];matrix[j][i] = temp;}}}
}

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

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

相关文章

【ChipIntelli 系列】ASR部分——合成语言模型和多网络(多语种)切换

打开 ChipIntelli 的AI开发平台,找到组件开发的语言模型开发。在页面中编辑语料然后下载文件 共有两个文件夹:拷贝两个文件夹下的文件到SDK中 以双网络为例: 如果您使用的是CI130X SDK,请按如下步骤将合成的文件拷…

dots.llm1:小红书开源的 MoE 架构大语言模型 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

哪些ERP系统值得长期使用?2025年最新盘点来了!

哪些ERP系统值得长期使用?2025年最新盘点来了!在数字化转型加速的背景下,企业对ERP系统的依赖日益加深。根据行业调研数据显示,持续应用集成化ERP系统的企业在运营效率、数据准确性和战略决策能力上较传统管理模式有…

商品网站建设设计思路dw怎么做网站

文章目录 一、redis1.1 redis概述1.2 redis安装 二、string2.1 基础命令2.2 存储结构2.3 应用 三、list3.1 基础命令3.2 应用 四、hash4.1 基础命令4.2 存储结构4.3 应用 五、set5.1 基础命令5.2 存储结构5.3 应用 六、zset6.1 基础命令6.2 存储结构6.3 应用 一、redis 1.1 re…

下载网站源码行业网站设计公司

文章来源&#xff1a;http://www.bjfhrd.com 体育木地板上有许多暗门&#xff0c;以制造特殊效果&#xff0c;如火焰、烟雾&#xff0c;使房屋、树木、山或人物在一瞬间出现或销售。这种特殊的要求&#xff0c;对于专业体育木地板德施工就有了一定的要求。 专业体育木地板施工&…

湖南教育平台网站建设查公司注册信息怎么查

转载自 关于SimpleDateFormat时间格式化线程安全问题昨天推送的文章《关于创建和销毁对象》一文中&#xff0c;2.1重复利用对象这一小节所举的SimpleDateFormat格式化时间的例子是不合适的&#xff0c;因为多线程场景下&#xff0c;SimpleDateFormat存在线程安全问题。在此&am…

网站的建设与维护需要资质吗网站设置子目录

HTTP HTTP版本HTTP2和HTTP3区别 HTTP版本 HTTP&#xff08;超文本传输协议&#xff09;的发展史可以分为以下几个版本&#xff1a; 1. HTTP/0.9&#xff1a;最初的版本只能传输HTML文本&#xff0c;并且没有header和body&#xff0c;仅支持GET请求。 2. HTTP/1.0&#xff1a…

如何对网站的图片做cdn如何做企业文化培训

1、什么是流 我们可以先想象水流是怎样的&#xff1f;溪水不断流动&#xff0c;最终融入大海&#xff1b;我们今天的学习IO其实如同水流一样&#xff0c;当我们读取文件信息或者写入信息时&#xff0c;如同水流一样&#xff0c;不断读取或者写入&#xff0c;直到业务流程结束。…

个人导航网站怎么备案网站上线准备

本文来自腾讯蓝鲸智云社区用户: CanWay 平台化工程涉及双重核心意义。一方面&#xff0c;是类似利用IDE等工具提高工程师效率的平台化工程&#xff0c;如GitOps或命令行调度般便捷。然而&#xff0c;本文重点探讨的是基于价值流的平台化工程&#xff0c;尤其针对传统金融行业&a…

部队网站模板html网页框架代码实例

分类算法之逻辑回归逻辑回归&#xff08;Logistic Regression&#xff09;&#xff0c;简称LR。它的特点是能够是我们的特征输入集合转化为0和1这两类的概率。一般来说&#xff0c;回归不用在分类问题上&#xff0c;因为回归是连续型模型&#xff0c;而且受噪声影响比较大。如果…

好看的单页面网站中小企业网站功能

#需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; 某企业根据自身业务需求&…

内网环境怎么安装软件(用 yum / apt 下载离线包并搬入内网)

目录内网环境怎么安装软件(用 yum / apt 下载离线包并搬入内网) 内网环境怎么安装软件(用 yum / apt 下载离线包并搬入内网) 很多同学觉得在内网装软件很简单:在有网络的机器上把包下载好,再拷贝到内网安装。思路…

tanh函数

tanh函数(双曲正切函数)是神经网络中一种常用的激活函数,它的数学表达式为: $$\tanh(x) = \frac{e^x - e{-x}}{ex + e^{-x}}$$ 它的输出范围是 $(-1, 1)$。 tanh函数的特点非线性:和 Sigmoid 函数一样,tanh 函数…

P13617 [ICPC 2024 APC] Bit Counting Sequence

P13617 [ICPC 2024 APC] Bit Counting Sequence对于一个非负整数 \(x\),令 \(p(x)\) 为 \(x\) 的二进制表示中 1 的个数。例如,\(p(26)=3\),因为 \(26=(11010)_2\)。 给定长为 \(n\) 的整数序列 \((a_1, a_2, ..., …

成都捕鱼网站建设做设计需要知道的几个网站

【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码 1 题目 题目 D 题 圈养湖羊的空间利用率 规模化的圈养养殖场通常根据牲畜的性别和生长阶段分群饲养&#xff0c;适应不同种类、不同阶段的牲畜对空间的不同要求&#xff0c;以保障牲畜安全和健康&a…

网页模板素材网站最新网球赛事新闻

烛秋 http://www.cnblogs.com/cswuyg/archive/2011/09/30/dll.html 动态链接库的使用有两种方式&#xff0c;一种是显式调用。一种是隐式调用。 &#xff08;1&#xff09; 显式调用&#xff1a;使用LoadLibrary载入动态链接库、使用GetProcAddress获取某函数地址。 &am…

如何修改网站底部重庆点优定制网站建设

文章目录 语法使用举例 $millisecond聚合运算符返回日期中毫秒部分的数字值为0到999之间 语法 { $millisecond: <dateExpression> }参数说明&#xff1a; <dateExpression>为可解析为Date、Timestamp或ObjectID或者参数也可以是一个文档&#xff1a; { date: &l…

淘宝网站模板是什么做的html中文网

dockerfiletodo item基础命令编写dockefiel基于centos镜像制作tomcatjdk的镜像todo item 是用来构建docker镜像的脚本&#xff1b;命令参数脚本。构建步骤:1、编写一个dockerfile文件2、 docker build 构建为一个镜像3、docker run 运行镜像4、docker push 发布镜像(dockerhub…

网站建设进度总结网站设为主页功能怎么做

前端技术知识&#xff08;含八股&#xff09;总结 - 持续更新中 参考文献1.HTML和CSS1.1 语义化标签1.2 CSS 选择器及优先级 / position 定位 / box-sizing 属性 / transition / 继承属性&#xff08;如字体文字类的属性大部分有继承&#xff09;/ 行内元素和块级元素 / html的…

装饰公司为什么做网站怎么区别网站开发语言

可以按这样的方式来存放 长度A 长度A 用于调整Short JMP 用于存放一些信息 |调整后的原HOOK代码 |原始代码(HOOK) |临时LONG JMP区| 信息区| 1). 调整…