LeetCode初级算法之数组:48 旋转图像
旋转图像
题目地址:https://leetcode-cn.com/problems/rotate-image/
给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
示例 1:
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
示例 2:
给定 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]
]
四指针
这一题与前面写到的旋转数组一题相似,之前是一维的,现在相当于是二维版。同样是两种思路一种是直接设置值到最终的地方,被覆盖的值先用备份变量拿出来再往它的目的地去设。第二种就是反转的思路。
旋转上图过程
(1)
backup = m[0][1]
m[0][1] = m[0][0]
(2)
temp = backup
backup = m[1][1]
m[1][1] = temp
(3)
temp = backup
backup = m[1][0]
m[1][0] = temp
(4)
m[0][0] = backup
由于是2×2所以一次旋转设值完事,如果是3×3
和之前那一题还是有点差别,这边设置值的传递固定是四个完成一组,然后需要判断一圈有多少组
1×1 0组
2×2 1组
3×3 2组
四次设置值是一个单元操作,之后指针变动第一个指针是水平向右移动,第二个指针是垂直向下其他依次,直到头length-1。那么外循环条件是有几圈2×2,3×3都只有一圈,4×4与5×5是两圈。也就是length/2圈,内循环为每圈要移动多少组数字它取决于终点索引,并且每往内一圈length都会少2两边都会靠近1格。
- 外圈(第一圈)起点
matrix[0][0]
终点matrix[0][2]
有三组 - 内圈(第二圈)起点
matrix[1][1]
终点matrix[1][1]
只有一组
也就是当外循环完毕内循环的起点是和外循环相同,也就是j = i然后j在往后递增直到终点,终点会往内圈慢慢递减
我们这里只看首指针的变化,其他一样推总结在代码里
- 第一圈从
[0][0]--->[0][4]
5组 - 第二圈从
[1][1]--->[1][3]
3组 - 第三圈就
[2][2]
1组
public void rotate(int[][] matrix) {
int n = matrix.length;
int s = n;
for (int i = 0; i < n/2; i++,s--) {
for (int j = i; j < s-1; j++) {
int backup = matrix[j][n-i-1];
matrix[j][n-i-1] = matrix[i][j];
int temp = matrix[n-i-1][n-j-1];
matrix[n-i-1][n-j-1] = backup;
backup = temp;
temp = matrix[n-j-1][i];
matrix[n-j-1][i] = backup;
backup = temp;
matrix[i][j] = backup;
}
}
}
总体实现了这样一个主线,但就是我们去存将被覆盖的值其实不需要另外添加一个变量backup我们可以直接把它存在首指针的地方,那个地方到最后才被设值中途是啥都没有关系我们就暂时用它存(空间已经存在了不用白不用)。
public void rotate(int[][] matrix) {
int n = matrix.length;
int s = n;
for (int i = 0; i < n/2; i++,s--) {
for (int j = i; j < s-1; j++) {
int temp = matrix[i][j]
matrix[i][j] = matrix[j][n-i-1];
matrix[j][n-i-1] = temp;
temp = matrix[n-i-1][n-j-1];
matrix[n-i-1][n-j-1] = matrix[i][j];
matrix[i][j] = temp;
temp = matrix[n-j-1][i];
matrix[n-j-1][i] = matrix[i][j];
matrix[i][j] = temp;
}
}
}
两次反转
第二种方式就反转和旋转数组一题一样我们直接观察输入图与目标图通过怎样的变换可以得到
旋转90度的关系肯定是没有直接方式的,这里我们肯定是用到的设值。通过图形变换反转类似的方式就两数交换完成就可能进行几组反转比起上面直接的一步的到位的设值方式在单元操作上两数交换比起四数看起来简一点。但有进行多组遍历的可能。它是转90而不是180如果是180就上下反转然后左右反转。所以这里只能对角反转加左右反转先后无所谓
无论怎么转都可以实现总之是通过两个数的交换就很简单,然后要进行两次。下面代码按照第一条进行,第一个变换只需要遍历左上一半即可每个完成和下面的交换即可因此列的起点是递增的j = i,第二个变换循环时列只需要左边一半就换行所以j = length/2
public void rotate(int[][] matrix) {
int n = matrix.length;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int tmp = matrix[j][i];
matrix[j][i] = matrix[i][j];
matrix[i][j] = tmp;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n / 2; j++) {
int tmp = matrix[i][j];
matrix[i][j] = matrix[i][n - j - 1];
matrix[i][n - j - 1] = tmp;
}
}
}
总结
总体来说都是一个原地算法,时间也都是O(n^2),像这一题与之前一题都是属于数组内原地的变化位置即多值交换以及换成多组反转即两值交换的组合。主要也是体会在数组这样的数据结构当中我们可以有的算法思想:遍历、逆序、原地交换、快慢指针。万变不离其中,那么从更新《LeetCode日常》系列开始到这篇为止LeetCode初级算法合集中的数组篇章完结即将开启下一篇章字符串相关算法
LeetCode初级算法之数组:48 旋转图像的更多相关文章
- LeetCode初级算法之数组:66 加一
加一 题目地址:https://leetcode-cn.com/problems/plus-one/ 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一.最高位数字存放在数组的首位, 数 ...
- 算法练习LeetCode初级算法之数组
删除数组中的重复项 官方解答: 旋转数组 存在重复元素 只出现一次的数 官方解答: 同一个字符进行两次异或运算就会回到原来的值 两个数组的交集 II import java.util.Arr ...
- LeetCode初级算法之数组:36 有效数独
有效数独 题目地址:https://leetcode-cn.com/problems/valid-sudoku/ 判断一个 9x9 的数独是否有效.只需要根据以下规则,验证已经填入的数字是否有效即可. ...
- LeetCode初级算法之数组:283 移动零
移动零 题目地址:https://leetcode-cn.com/problems/move-zeroes/ 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺 ...
- LeetCode初级算法之数组:350 两个数组的交集 II
两个数组的交集 II 题目地址:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/ 给定两个数组,编写一个函数来计算它们的交 ...
- LeetCode初级算法之数组:136 只出现一次的元素
只出现一次的元素 题目地址:https://leetcode-cn.com/problems/single-number/ 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找 ...
- LeetCode初级算法之数组:189 旋转数组
旋转数组 题目地址:https://leetcode-cn.com/problems/rotate-array/ 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输 ...
- LeetCode初级算法之数组:122 买卖股票的最佳时机 II
买卖股票的最佳时机 II 题目地址:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/ 给定一个数组,它的第 i ...
- LeetCode初级算法之数组:1 两数之和
两数之和 题目地址:https://leetcode-cn.com/problems/two-sum/ 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整 ...
随机推荐
- python_选课系统
import sys import pickle import os USERINFO = r'C:\Users\12078\PycharmProjects\OldBoy\选课系统\userinfo' ...
- gdb 调试 报 stepping until--- has no line number information
gdb 经常用 ,但今天使用gdb 调试的时候, break 打断点, 结果也没有打出 哪一行的信息,就只是提示一个具体地址. 使用单步调试 结果爆出 stepping until exit from ...
- 极客mysql38
InnoDB 引擎把数据放在主键索引上,其他索引上保存的是主键 id.这种方式,我们称之为索引组织表(Index Organizied Table). 而 Memory 引擎采用的是把数据单独存放,索 ...
- minishell的实现
直接上各个模块的代码,注释都在文档代码中,非常详细,加上最后的Makefile文件完全可以自行运行看懂: main函数一个文件main.c 1 /* 2 minishell实现的功能:简单命令解析.管 ...
- js 及jQery
1.jQuery即是对象也是类. 2.append()方法的使用,连加操作. 例子: $(function(){ var obj=new Object(); obj.id=$("input[ ...
- Ceph实现数据的'不拆分'
前言 之前看过一个朋友一篇文章,讲述的是Vsan为什么使用的是两副本,而ceph则大多数情况下需要三副本,当时个人观点是这个并不是关键点,但是在仔细考虑了问题的出发点以后,这个也可以说是其中的一个点 ...
- Python_异常处理、调试
1.try except 机制 # 错误处理 # 一般程序都要用到错误捕获,当没有加且有错误的时候Python解释器会执行错误捕获,且是一层层向上捕获[所以问题点会在最下面] try: print(' ...
- 部署sftp服务
部署sftp服务有风险,可能造成ssh无法连接到服务器,因此写个脚本定时覆盖一下,保证ssh可以正常使用. 创建数据目录并赋权,创建账号密码,修改ssh文件. * mkdir /sftp groupa ...
- springboot实战开发全套教程,让开发像搭积木一样简单!Github星标已上10W+!
前言 先说一下,这份教程在github上面星标已上10W,下面我会一一给大家举例出来全部内容,原链接后面我会发出来!首先我讲一下接下来我们会讲到的知识和技术,对比讲解了多种同类技术的使用手日区别,大家 ...
- 精尽MyBatis源码分析 - SQL执行过程(二)之 StatementHandler
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...