力扣【48-旋转图像】【数组-C语言】

devtools/2024/10/17 18:33:42/

题目:leetcode.cn/problems/rotate-image/description/" rel="nofollow">力扣-48

给定一个 n × n 的二维矩阵 M 表示一个图像。请你将图像顺时针旋转 90 度。你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像

在这里插入图片描述
写代码之前先分析矩阵旋转的本质:
矩阵顺时针旋转90°就是矩阵的第一行变为倒数第一列,第二行变为倒数第二列,第三列变为倒数…(仅看行),相当于平时拿手机时竖着看,现要看电影手机则横着放。再看下对应的数字位置的变化情况,我们把矩阵中的每个元素所在的行列看作在平面坐标系下的坐标。以示例2中矩阵第一个数字(5)为例,数字5会移动到数字11的位置上,11移动到数字16的位置上,15移动到5数字最初的位置,这就是顺时针旋转90°后,一个元素的位置变化(一个数字位置的变化会导致其他数字位置相应的变化,我把这些变化的位置串起来(路径)称为“一轮”),下面列举第一行每个数字一轮后的位置变化路径。

注:总共nxn的矩阵,其中n=4,同时(i,j) 表示:i行,j列,
第一个数字(5)5  --> 11  --> 16  --> 15  --> 5(最初位置)
(0,0)-->(0,3)-->(3,3)-->(3,0)-->(0,0)
观察发现:数字的下一个位置的行坐标就是上一个位置的列坐标,即上一个位置(i,j),则下一个位置的坐标(j,x)  x表示未知,目前暂时看不出什么变化
但注意上面提到的:第一行(行坐标就是i)旋转后变为倒数第一列(总共列数为n,列坐标范围0~(n-1)),试着列出列坐标j的表达式:j=(n-1)-i,带入上数字验证没问题,下面两个可以接着验证,这里就不在赘述。第二个数字(1)1  --> 10  --> 12  --> 13  -->  1(最初位置)
(0,1)-->(1,3)-->(3,2)-->(2,0)-->(0,1)
第三个数字(9)9  -->  7  --> 14  -->  2  -->  9(最初位置)
(0,2)-->(2,3)-->(3,1)-->(1,0)-->(0,2)
...最终:我们得出矩阵(用M表示)中数字M[i][j],经过旋转后新的位置为:(j,n-i-1),即 M[j][n-i-1]
注意:看整体:第一行变为倒数第一列(位置关系已给出),原倒数第一列变为最后一行,原最后一行变为第一列,原第一列变为第一行。

方法一:采用辅助数组

思路:用一个和矩阵M大小一致的辅助数组M_new(二维数组),遍历矩阵M,把位置(i,j)上的数字移动到新数组(j,n-i-1)位置上,最后在把新数组拷贝到原来矩阵M里即可(代码略)

方法二:原地移动数字(空间复杂度为O(1))

思路:由前面的分析可知,一个数字一轮后,总共要移动四个方向的数字各一次(上—>右---->下---->左---->上)共4次,而每个数字的新位置和前面分析位置变化的思路一致(代码实现里略微不一样)

void rotate(int** M, int matrixSize, int* matrixColSize) {int n = matrixSize;int t1, t2;//临时变量for (int i = 0; i < matrixSize / 2; i++) {for (int j = i; j < n - 1 - i; j++) {t1 = M[j][n - i - 1];//保存M[i][j]的下一个位置上的数字t2 = 0;M[j][n - i - 1] = M[i][j];//数字M[i][j]移动好了t2 = M[n - i - 1][n - j - 1];//保存数字M[j][n-i-1]的新位置上的数字,注:行:j,列:n-j-1,和前面分析的差不多,只是符号变了,意义没变。M[n - i - 1][n - j - 1] = t1;//数字M[j][n-i-1]移动好了t1 = M[n - j - 1][i];M[n - j - 1][i] = t2;M[i][j] = t1;//一轮的最后一个要移动的数字,移动到最初位置}}
}

方法三:(用翻转代替旋转)

思路:这里就不多加描述,其数字移动的本质还是和前面分析的思路一致(公式一致)


http://www.ppmy.cn/devtools/126530.html

相关文章

[数据结构]带头双向循环链表的实现与应用

文章目录 一、引言二、链表的基本概念1、链表是什么2、链表与顺序表的区别3、带头双向循环链表 三、带头双向循环链表的实现1、结构体定义2、初始化3、销毁4、显示5、数据操作 四、分析带头双向循环链表1、存储方式2、优点3、缺点 五、总结1、练习题2、源代码 一、引言 链表作…

【exceljs】纯前端如何实现Excel导出下载和上传解析?

前段时间写过一篇类似的文章&#xff0c;介绍了sheetjs。最近发现了一个更好用的库ExcelJS&#xff0c;它支持高级的样式自定义&#xff0c;并且使用起来也不复杂。实际上sheetjs也支持高级自定义样式&#xff0c;不过需要使用付费版。 下面对比了Exceljs和Sheetjs&#xff1a…

10月15日,每日信息差

第一、《哈利・波特与魔法石》在中国内地总票房突破 3 亿元&#xff0c;包括 2002 年首映的 5600 万&#xff0c;2020 年重映的 1.923 亿&#xff0c;以及 2024 年重映的 5170 万。 第二、全国铁路实施新货物列车运行图&#xff0c;增开城际班列至 131 列&#xff0c;多式联运…

跨站请求伪造(CSRF,Cross-Site Request Forgery)

跨站请求伪造&#xff08;CSRF&#xff0c;Cross-Site Request Forgery&#xff09;是一种网络攻击方式&#xff0c;它允许攻击者在用户不知情的情况下&#xff0c;以用户的名义执行非授权的命令。这种攻击利用了用户已经验证的身份和信任关系&#xff0c;来执行恶意操作。 一…

【C#生态园】窥探C#短信发送库:安装配置指南和发送接收短信API概览

探究C#短信发送库&#xff1a;核心功能、使用场景和API概览 前言 随着移动技术的快速发展&#xff0c;短信服务在软件开发中变得越来越重要。为了简化短信发送过程&#xff0c;许多库和API都已经被开发出来&#xff0c;以便于在不同编程语言中进行短信发送操作。本文将重点介…

Android 自定义Toast显示View

1、创建一个tosat显示的布局文件&#xff1a;toast_custom.xml <?xml version"1.0" encoding"utf-8"?> <com.hjq.shape.layout.ShapeLinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width&…

数据链路层数据帧格式及网络层IP数据包格式

数据帧格式 前导码&#xff1a;进入物理层之前的缓冲区&#xff0c;包含的是7个字节&#xff08;56比特&#xff09;交替出现的0和1&#xff0c;作用&#xff1a;提醒接受系统有帧到来&#xff0c;并且使它与输入定时同步 帧起始定界符&#xff1a;1字节&#xff08;8比特&…

推荐算法的学习

文章目录 前言1、模型1.1 从本领域模型的发展历史中学习1.1.1 在历史中总结发展规律和趋势1.1.2 发现模型之间的共性&#xff0c;方便记忆 1.2 从其他领域的发展中学习1.2.1 注意力机制1.2.2 残差网络 1.3 实践该怎么办&#xff1f; 2、 特征2.1 数据源的选择与建立2.2 特征构造…