旋转图像

题目地址: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 旋转图像的更多相关文章

  1. LeetCode初级算法之数组:66 加一

    加一 题目地址:https://leetcode-cn.com/problems/plus-one/ 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一.最高位数字存放在数组的首位, 数 ...

  2. 算法练习LeetCode初级算法之数组

    删除数组中的重复项 官方解答: 旋转数组 存在重复元素 只出现一次的数     官方解答:  同一个字符进行两次异或运算就会回到原来的值 两个数组的交集 II import java.util.Arr ...

  3. LeetCode初级算法之数组:36 有效数独

    有效数独 题目地址:https://leetcode-cn.com/problems/valid-sudoku/ 判断一个 9x9 的数独是否有效.只需要根据以下规则,验证已经填入的数字是否有效即可. ...

  4. LeetCode初级算法之数组:283 移动零

    移动零 题目地址:https://leetcode-cn.com/problems/move-zeroes/ 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺 ...

  5. LeetCode初级算法之数组:350 两个数组的交集 II

    两个数组的交集 II 题目地址:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/ 给定两个数组,编写一个函数来计算它们的交 ...

  6. LeetCode初级算法之数组:136 只出现一次的元素

    只出现一次的元素 题目地址:https://leetcode-cn.com/problems/single-number/ 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找 ...

  7. LeetCode初级算法之数组:189 旋转数组

    旋转数组 题目地址:https://leetcode-cn.com/problems/rotate-array/ 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输 ...

  8. LeetCode初级算法之数组:122 买卖股票的最佳时机 II

    买卖股票的最佳时机 II 题目地址:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/ 给定一个数组,它的第 i ...

  9. LeetCode初级算法之数组:1 两数之和

    两数之和 题目地址:https://leetcode-cn.com/problems/two-sum/ 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整 ...

随机推荐

  1. [MIT6.006] 22. Daynamic Programming IV: Guitar Fingering, Tetris, Super Mario Bro. 动态规划IV:吉他指弹,俄罗斯方块,超级玛丽奥

    之前我们讲到动态规划五步中有个Guessing猜,一般情况下猜有两种情况: 在猜和递归上:猜的是用于解决更大问题的子问题: 在子问题定义上:如果要猜更多,就要增加更多子问题. 下面我们来看如果像背包问 ...

  2. 利用HUtool读取Excel内容

    // 1.获取上传文件输入流 InputStream inputStream = null; try{ inputStream = file.getInputStream(); }catch (Exc ...

  3. readonly和disabled的区别!

    Readonly只针对input(text / password)和textarea有效 Disabled对于所有的表单元素都有效 readonly接受值更改可以回传,disable接受改但不回传数据 ...

  4. Boost命令行解释器的简单使用:Boost.Program_options

    简介 如果使用比较多的命令行程序的话,对于命令行参数的输入肯定不会陌生,大部分的程序都是通过类似下面的形式进行输入的,比如熟悉的ls ls --all -l --color=auto 这里面包含了三种 ...

  5. 精尽 MyBatis 源码分析 - 整体架构

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  6. Collectiont和Collections的区别

    Collectiont 和 Collections 的区别 Collection: 是Java提供的集合接口 存储一组不唯一,无序的对象 有两个子接口 List 和 Set Collections: ...

  7. php(tp5)生成条形码

    因为公司业务需要,研究了一下条形码 1.下载barcodegen扩展包 官网地址:https://www.barcodebakery.com 2.下载完后解压至 extend 文件夹里面,然后复制以下 ...

  8. 阿里云的nginx的https配置问题

    server { listen 443 ssl; server_name www.xxx域名.com; root html; index index.html index.html; ssl_cert ...

  9. 这个厉害了,阿里P7大佬都在看的SpringCloud 总结,帮你梳理全部知识点!

    微服务 微服务架构是一种以一些微服务来替代开发单个大而全应用的方法,每一个小服务运行在自己的进程里,并以轻量级的机制来通信, 通常是 HTTP RESTful API.微服务强调小快灵, 任何一个相对 ...

  10. FL Studio中如何制作和混音Dutch Lead(上)

    Dutch Lead是电子音乐类型Dutch House以及Bigroom House中常用的Lead音色,这一篇文章中我将从制作和混音两方面来讲解Dutch Lead. (一).Dutch Lead ...