图解翻转矩阵问题
matrix
0.如何将一张图翻转90度
给定一张图片,如何将它旋转 90 度? 可以将图视为可以存储在缓冲区中的二维矩阵。 提供了矩阵维度和它的地址。 怎么转呢?
下面的是个例子
* * * ^ * * *
* * * | * * *
* * * | * * *
* * * | * * *顺时针翻转90度后,变成:
* * * *
* * * *
* * * *
-- - - >
* * * *
* * * *
* * * *想法很简单,将源矩阵的每一行转换为最终图的所需列,将使用辅助缓冲区来转换图。 从上图我们可以观察到
源图的第一行 -> 目标图的最后一列
源图的第二行 -> 目标图的倒数第二列
...
源图的最后一行 -> 目标图的第一列
如图:可以将m✖️n的矩阵转化为n✖️m矩阵,逻辑如下:
代码
输出
1.如何原地将矩阵旋转90度
比如说需要将下面的矩阵逆时针旋转90度
在第一部分已经讨论过,如果利用多余的空间翻转矩阵了,本部分讨论下如何原地空间复杂度的方式翻转矩阵
思路
要在没有多余空间的情况下解决问题,将数组旋转为正方形,将矩阵划分为正方形或环。
例如,一个 4✖️4 的矩阵将有 2 个环。
第一个环由它的第一行、最后一列、最后一行和第一列组成。
第二个环由第二行、倒数第二列、倒数第二行和第二列组成。
这个想法是对于每个方形循环,以逆时针方向交换与矩阵中相应单元格相关的元素,即从上到左、从左到下、从下到右和从右到上一次,只使用一个临时变量来实现这一点。
图解结果如下:

算法
1.在N边的矩阵中有N/2个正方形或环。一次处理一个正方形,运行一个环,一次遍历矩阵一个环,即从 0 循环到 N/2 – 1,循环计数器为 i。
2.考虑当前正方形中的 4 个元素组,一次旋转 4 个元素。 因此,一个循环中此类组的数量为N – 2*i。
3.所以在从 x 到 N - x - 1 的每个循环中运行一个环,循环计数器为 y。
4.当前组中的元素是 (x, y), (y, N-1-x), (N-1-x, N-1-y), (N-1-y, x),现在旋转这4个元素,即(x, y) <- (y, N-1-x), (y, N-1-x)<- (N-1-x, N-1-y), (N- 1-x, N-1-y)<- (N-1-y, x), (N-1-y, x)<- (x, y)

代码
输出
复杂度分析
时间复杂度:O(n*n) 其中n是矩阵的长度
空间复杂度: O(1),没有使用到额外的空间,只是一个变量
不过还有另外一种思路:
1.翻转每一行
2.执行转置
2.再论如何原地将矩阵旋转90度
上面已经讨论了如何进行原地的矩阵翻转了,下面再给出另外一种思路

主要的思路是:将矩阵的转置,然后反转转置矩阵的列。
算法
1.为了解决给定的问题,有两个任务。 第一个是找到转置,第二个是在不使用额外空间的情况下反转列。
2.矩阵的转置是当矩阵翻转其对角线时,即元素的行索引变为列索引,反之亦然。 因此,要找到转置,将位置 (i, j) 处的元素与 (j, i) 互换。执行两个循环,外循环从 0 到行数,内循环从 0 到外循环的索引。
3.要反转转置矩阵的列,请运行两个嵌套循环,外循环从 0 到列数,内循环从 0 到行数/2,将 (i, j) 处的元素与 (i, row[count-1 -j])对调,其中 i 和 j 分别是内循环和外循环的索引。
代码
输出
复杂度分析
时间复杂度:O(R*C) 其中R和C是矩阵的行列
空间复杂度: O(1),没有使用到额外的空间
3.如何原地将矩阵旋转180度
上面的两部分解决了如何旋转90度的问题,那么180度怎么处理?
例子:
方法1(仅打印旋转矩阵)

从上图中,可以简单地将矩阵旋转180度,以相反的方式打印给定的矩阵。
代码
输出
复杂度分析
时间复杂度:O(N*N) 其中N是矩阵的行列
空间复杂度: O(1),没有使用到额外的空间
方法2:原地翻转(转置翻转列两次)
算法
1.查找矩阵的转置。
2.反转转置的列。
3.找到矩阵的转置。
4.转置的反转列

输出
复杂度分析
时间复杂度:O(R*C) 其中R和C是矩阵的行列
空间复杂度: O(1),没有使用到额外的空间
方法3:位置交换
上面的方式其实是将矩阵翻转90度做了两次,其实有更好的方法

输出
4.将矩阵的每个环逆时针旋转 K 个元素
给定一个 M*N 阶矩阵和一个值 K,将矩阵的每个环逆时针旋转 K 个元素。 如果任何环中的元素小于等于 K,则不要旋转它。
思路
想法是以螺旋形式遍历矩阵, 这是解决这个问题的算法:
1.创建一个大小为 M*N 的辅助数组 temp[]。
2.以螺旋形式开始遍历矩阵并将当前环的元素存储在 temp[] 数组中。 在将元素存储在 temp 中时,跟踪当前环的开始和结束位置。
3.对于存储在 temp[] 中的每个环,旋转该子数组 temp[]
4.对矩阵的每个环重复此过程。
5.在最后一次遍历矩阵中再次螺旋并将 temp[] 数组的元素复制到矩阵。
有了上面的这些铺垫,可以来解决几道题目:
题目要求的是原地旋转,顺时针旋转
参考1.如何原地将矩阵旋转90度,挪动下调换的坐标即可

也可以参考2.再论如何原地将矩阵旋转90度,在做第二步翻转的时候,将行翻转变成列翻转

这一题等同于48题
这一题只需要用到转置的那段代码即可,但是这一题m*n的矩阵,m和n可能不相同,所以用到额外空间,简单模拟即可
Last updated