LeetCode--48.旋转图像(个人解题思路)

题目内容

旋转图像题目链接
给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 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]]

示例 3
输入matrix = [[1]]
输出:[[1]]

示例 4
输入matrix = [[1,2],[3,4]]
输出:[[3,1],[4,2]]

图片示例

示例略显苍白,leetcode上也有图像表示,我这里也自己画了一个 5 X 5 的二维矩阵展示该题需要我们去做些什么,接下来我会以我的示例作为基础,对我这道题的解题思路进行讲解,方法可能略显笨拙,还请各位大神勿喷勿喷~,那么如下图所示,开启我们对这道题的探索!
题目图片示例
如图,我们看到了左边的矩阵图像,就把它叫做TransBefore=[[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20],[21,22,23,24,25]];而右边的矩阵就把它叫做TransAfter=[[21,16,11,6,1],[22,17,12,7,2],[23,18,13,8,3],[24,19,14,9,4],[25,20,15,10,5]]。好了,现在图片已经有了,那我们应该去好好思考一下如何将Transbefor -> TransAfter? 话不多说,我们开始解题!

个人解题思路

二维矩阵结构

在谈论这道题解题思路的同时,我们也去刨析下二维矩阵的结构。要知道呀,这道题是不允许我们用额外的二维矩阵进行存储作为返回结果,那我们就需要原地修改值(矩阵传进来,返回值还是这个矩阵,一切都是对矩阵本身进行操作)。而原地修改矩阵就会造成一个小小的困难,也就是我某个值变到了目标值的位置,那么我的目标值位置里原来存的值应该去哪里呢?这里先跳出第一种想法,就是互换,那我们先看下代码和结果:

TransBefore=[[1, 2, 3, 4, 5 ],
             [6, 7, 8, 9, 10],
             [11,12,13,14,15],
             [16,17,18,19,20]
             [21,22,23,24,25]]
#比如我这里[0][0]位置 -> [0][4]位置
TransBefore[0][0] , TransAfter[0][5] = TransAfter[0][5] , TransBefore[0][0]

"""
[[5, 2, 3, 4, 1 ],
 [6, 7, 8, 9, 10],
 [11,12,13,14,15],
 [16,17,18,19,20]
 [21,22,23,24,25]]
 结果就是TransBefor就变成了这个样子。
 数值25这个位置本应该换成数值5,此时我们要去原来5的位置找数,找不到了,因为5这个值的位置已经变了,感觉一切都很混乱了...
"""

既然这样,我们不如好好去找找二维矩阵内部,数值坐标之间存在的潜在关系,我们先以“1,5,25,21” 这四个值为例,去探究一种规律,理清换值思路,那我们先把他们的坐标罗列出来:
1: (0 , 0)
5: (0 , 4)
25:(4 , 4)
21:(4 , 0)
我们可以观察到,由于这些值存在的行列特殊性(之间存在或“同行”或“同列”),发现坐标规律!数值的横坐标是前一个值的纵坐标,1这个值的横坐标便是21的纵坐标。思考一下这样是不是就形成了一个环状呀,那我们只要让这四个值同时移向下一个值的位置就可以了,这一部分的逻辑的图像及代码如下:
环形换值逻辑图

#这里我们继续用TransBefore做例子
tmp = matrix[0][4]
matrix[0][4] = matrix[0][0]
hold = matrix[4][4]
matrix[4][4] = tmp
tmp = matrix[4][0]
matrix[4][0] = hold
matrix[0][0] = tmp

#其实互换值的方法里也有一种思路
tmp = matrix[0][4]
matrix[0][0] , matrix[0][4] = matrix[0][4] , matrix[0][4]
matrix[4][4] , tmp = tmp , matrix[4][4]  #此时,tmp中,由原来存放的matrix[0][4]变为了matrix[4][4]
matrix[4][0] , tmp = tmp , matrix[4][0] 

环形转动!

上面写了两种转换思路,虽然第一种看起来要复杂,但我更喜欢第一种,可能是我比较愚笨吧(第一种读下来可以明显感觉到值的交换是环形转动的),这就可以抛出接下来的一个问题,我们如何让矩阵里的所有值都经过这种转动,进而完成转换?那么请看下图:
环形转动思路图
由最上面的图片示例,我们可以看到旋转图像的最终结果就是依次对我们上图中三个环形上的所有数值按照我们之前想好的环形换值逻辑进行交换,进而形成最终结果。回到图像中我们总结下环形规律,我们可以看到 5 X 5 矩阵是三个环,但是!最后一个13是要孤独终老的,所以根本不用转动,这样一来 5 X 5 的矩阵只有两个环需要转。干脆将 1 X 1 到 5 X 5 的矩阵都画出来,看看规律如何?
矩阵环形规律
由上图我们可以看到,1 X 1 矩阵 = 0个环形 、2 X 2 矩阵 = 1个环形 、3 X 3 矩阵 = 1个环形 、4 X 4 矩阵 = 2个环形 、5 X 5 矩阵 = 2个环形 。由此,我们可以总结出:环形个数 = 矩阵规模除以2n//2)!!!

我的题解代码

经过上面的讨论,这道题的解题关键有两点:1.值的环形替换2.确定有几个环形。严格把握住这两点我们就可以开开心心地解开此题,顺利地旋转我们的矩阵图像。

def rotateMatrix(matrix):
	#width表示 矩阵规模。
    width = len(matrix)
    #times表示 我们此时正在第几环上进行值的替换。
    for times in range(width//2):
    	#round表示 我们在位这个环的第几轮值进行替换,其实规模为 5 的环只需要 4 次就可以转换完成。
        #由上述类推,若当前换规模为 k 那么执行 k-1可以完成值的替换。
        #环规模反映到矩阵中,我们循环的起止应为:times 到 width-times-1
        for round in range(times,width-1-times):
            tmp = matrix[round][width-1-times]
            matrix[round][width-1-times] = matrix[times][round]
            hold = matrix[width-1-times][width-1-round]
            matrix[width-1-times][width-1-round] = tmp
            tmp = matrix[width-1-round][times]
            matrix[width-1-round][times] = hold
            matrix[times][round] = tmp
    return matrix
if __name__ == "__main__":
    matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    print(rotateMatrix(matrix))

题目总结

题目成绩
这道题其实在换值部分也确实存在一些冗余,造成执行时间上不尽人意,相信互换值的方式会更好一些。对于这道题的题解与讨论还有好多,可以去这道题的解法中寻找更加有趣的思路:题解
小菜一枚,还在成长,讲述如有不妥,请各位大神指教 0.0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值