标题
题目
题目链接
给出一个矩阵,按顺时针螺旋顺序输出
例:
矩阵
输出
①一般递归解法
思路
对矩阵进行螺旋绕圈输出,相当于一层一层输出,如图所示:
可以得到递归解法:
设置dst
数组保存螺旋遍历的结果
- 若矩阵中没有元素了,退递归
- 若矩阵只有
1行
,把这一行元素加入dst
,退递归 - 若矩阵只有
1列
,把这一列元素加入dst
,退递归 - 若矩阵形状
>1行1列
,把矩阵外层
元素顺时针加入dst,对内层
矩阵继续递归
顺时针取矩阵外圈
用了切片和列表生成式,也可以普通for循环
取内层矩阵
要取矩阵matrix的内层,可以用列表生成式:[a[1:-1] for a in matrix[1:-1]]
代码
class Solution:
def rr(self, matrix, dst):
# 为空
if not matrix or not matrix[0]:
return
# 只有1行
elif len(matrix) == 1:
dst += matrix[0]
return
# 只有1列
elif len(matrix[0]) == 1:
dst += [matrix[i][0] for i in range(len(matrix))]
return
# >1行1列的情况,取外圈
else:
dst += matrix[0][:-1]
dst += [matrix[i][-1] for i in range(len(matrix) - 1)]
dst += matrix[-1][-1:0:-1]
dst += [matrix[i][0] for i in range(len(matrix) - 1, 0, -1)]
# 取数组的内层,继续递归
self.rr([a[1:-1] for a in matrix[1:-1]], dst)
def spiralOrder(self, matrix):
dst = []
self.rr(matrix, dst)
return dst
②一种简单的python解法
参考:https://blog.nowcoder.net/n/9157db534a4945b1a3edd2b0c183a078?f=comment
思路
每次取矩阵的第一行,将矩阵剩下的部分逆时针旋转90度
此时剩下的部分的第一行即为原本下一次要输出的内容
用zip(*)转置矩阵
zip有2种用法,zip(matrix1,matrix2...)
和zip(*matrix)
zip()
zip(matrix1,matrix2...)
的功能:把多个列表的元素按纵向对应位置打包,如果这多个列表不一样长,以最短的为准
如图有a,b两个列表:
对a,b进行zip,并转为list输出:
得到:
可以看出打包了(a[0],b[0])
和(a[1],b[1])
,由于b比a短,a多出来的元素未被打包
打包后的二维矩阵和原矩阵是转置
关系,且每一行的格式为元组
zip(*)
zip(*matrix)
是zip()的逆操作,效果为把一个矩阵转置
例:
有一个矩阵mat,对mat进行zip(*)操作:
输出为mat的转置:
zip(*)和[::-1]实现矩阵逆时针旋转
由于矩阵转置
相当于顺时针
旋转了90°,想要实现逆时针
旋转90°,可以:先转置,再对行进行倒序,即为逆时针旋转的效果
[::-1]
[::-1]
是python切片的一种用法,python切片的格式为[开始位置:结束位置:步长]
,开始位置和结束位置缺省时默认为整个list,当步长为-1
时表示倒序
所以[::-1]
表示:将list倒序
用zip(*)和[::-1]实现矩阵逆时针旋转图示:
代码
class Solution:
def spiralOrder(self , matrix):
res=[]
while matrix:
# 取矩阵第一行
res+=matrix[0]
# 把矩阵剩下的部分逆时针旋转90度
# 方法:取剩下的矩阵,先转置,再倒序
matrix=list(zip(*matrix[1:]))[::-1]
return res