故事要从前几个月刷剑指offer的时候说起,那时候遇到过一个关于二维数组的问题,问题如下
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
遇到这个问题我的第一个念头就是要是可以把二维数组旋转一下,然后不断打印第一行后移除掉就可以了,然后我就去搜集资料,看了一种旋转方法就被惊艳到了好6的算法。以下是我的解法
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
res = []
while matrix:
res += matrix[0]
matrix.remove(matrix[0])
if matrix:
matrix[:] = map(list, zip(*matrix))[::-1]
return res
python的特性使得可以在一行之内就完成数组的旋转操作。接下来解释一下是怎么旋转的
首先说一下 zip 函数:
a = [[1,2,3],
[4,5,6],
[7,8,9]]
zip(*a)
# 经过zip的压缩得到的结果如下
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
到这里我们其实就已经明白了这个函数的作用,zip本来就是压缩,在这里就是直接将一个二维数组纵向压成了一个一维的。
这个时候我们再把其中压缩后产生的元组转换回list看看它变成了什么样子
map(list,zip(*[[1,2,3],[4,5,6],[7,8,9]]))
# 经过map转换的list的得到的结果如下
[[1, 4, 7],
[2, 5, 8],
[3, 6, 9]]
# 而我们期望得到的矩阵是这样的
[[7, 4, 1],
[8, 5, 2],
[9, 6, 3]]
# 他们两个是左右相反的,到了这里我们已经明白了原理,将他左右颠倒还不简单,
# 利用python的slice特性[::-1]就可以了呗
matrix[:] = map(list,zip(*a))[::-1]
我们已经知道了原理所以无论是以后遇到顺时针或者逆时针旋转二维数组,我们一行代码都可以玩的转