leetcode 48 矩阵旋转可以这么简单
一行代码解决矩阵旋转(方法三)。
方法1:
坐标法
1 def rotate(self, matrix): 2 n = len(matrix) # 求出矩阵长度 3 m = (n + 1) // 2 # 求出层数 4 for k in range(m): 5 t = n - 2 * k - 1 # 需旋转的次数 6 for i in range(t): 7 # 不考虑 i 考虑 i 8 # d1(左上),行与k成正比,列与k成正比且与i成正比 [k][k] ---------------》 [k][k + i] 9 # d2(左下),行与k成反比且与i成反比,列与k成正比 [n - 1 - k][k] [n - 1 - k - i][k] 10 # d3(右下),行与k成反比,列与k成反比且与i成反比 [n - 1 - k][n - 1 - k] [n - 1 - k][n - 1 - k - i] 11 # d4(右上),行与k成正比且与i成正比,列与k成反比 [k][n - 1 - k] [k + i][n - 1 - k] 12 temp = matrix[k][k + i] #k代表层 13 matrix[k][k + i] = matrix[n - 1 - k - i][k] # k层 左上角 行不变 左下角 列不变 14 matrix[n - 1 - k - i][k] = matrix[n - 1 - k][n - 1 - k - i] 15 matrix[n - 1 - k][n - 1 - k - i] = matrix[k + i][n - 1 - k] 16 matrix[k + i][n - 1 - k] = temp
解释代码:
这里的坐标是不是很晕,这个是如何对应起来的呢?
1、首先我们把矩阵的每一圈看做一次操作(底下的红色圈代表一次调整)
对于宽度为n的我们需要 n/2次调整就可以结束。 这个次数为外层循环 K
2、对于每一次调整我们需要进行多次操作,因为每一次我们调整四个点(图中黑点)
每次往内缩缩小了2个格子 每一次内部调整次数为 n-2*k -1
3、现在外部循环为1 中次数 内部为 2中次数,那么坐标关系怎么处理呢?
只考虑1 考虑2
d1(左上)[k][k] [k][k+i]
d2(左下)[n - 1 - k][k] [n - 1 - k - i][k]
d3(右下)[n - 1 - k][n - 1 - k] [n - 1 - k][n - 1 - k - i]
d4(右上)[k][n - 1 - k] [k + i][n - 1 - k]
第一步:我们先不考虑2 只考虑1中坐标变化关系 每一个点都是往内部走k为层数(对照上述的关系看)
当k变化时 d1(左上)坐标[0+k][0+k] 与k均成正比 d2(左下)坐标[n - 1 - k][k] 横坐标反比 纵坐标正比 以此类推。。。。。。
第二步:现在考虑1
左上角坐标内部调整时,下一个为它右侧,纵坐标 ++
左下角坐标内部调整时,下一个为它上侧,横坐标 --
右下角坐标内部调整时,下一个为它左侧,纵坐标 --
右上角坐标内部调整时,下一个为它下侧,横坐标 ++
方法2(先对矩阵转置,然后进行水平翻转):
1 class Solution1: #转置和水平翻转两个步骤。 2 def rotate(self, matrix) -> None: 3 for i in range(len(matrix)): 4 for j in range(i, len(matrix[0])): 5 matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] 6 7 for row in matrix: 8 row.reverse()
方法3(一行代码实现,巧用ZIP函数):
1 def rotate1(self, matrix): 2 matrix[:] = list(map(list,zip(*matrix[::-1])))
我们看看方法三做了什么?
[[1,2,3],
[4,5,6],
[7,8,9]]
先对矩阵进行了逆序:
1 test = [[1,2,3], 2 [4,5,6], 3 [7,8,9]] 4 print(test[::-1]) 5 print(list(zip(*test[::-1]))) #解压之后内部为元组,所以使用map迭代式 list 6 print(list(map(list,zip(*test[::-1]))))