Leetcode 54 螺旋矩阵
剑指Offer 29.顺时针打印矩阵(同理)
官方给出的答案和我找到的一些其它答案都说的不是很清晰,这里整理出一下一份答案。
要点总结:
1、关于行和列有可能是奇数还是偶数的问题,不需要纠结,只要循环的往出打印就可。
2、遵守左闭右开的原则,遵守一个方向原则。
3、每打印一行,检查一下返回数组的长度是否够了,免去许多不必要的麻烦。
4、最后遍历完还是不够的话,再补上最中间的小格子
5、实际上是,只有当行和列都是奇数的情况下,最后一个空填不出来。
6、left和right,up和down可以等于,跟 59.螺旋矩阵II 略有一些差别。
# 54. 螺旋矩阵
# 1.0 总结:不要纠结奇数和偶数行和列的关系,你就循环的输出,只要数量够了就return
# 要是最后数量还是不够,那就不是奇数偶数的问题了,然后发现最后没填满的情况都是 行和列都是奇数的,说明正好旋转到最后那个小格子没办法继续了
# 再补充上最后那个小格子就行
class Solution:
def spiralOrder(self, matrix: list[list[int]]) -> list[int]:
order = list() # 创建空列表,存放螺旋打印的东西
# if not matrix or len(matrix) == 0:
if not matrix or not matrix[0]: # 如果传入空矩阵或者没有 矩阵的第一行就是0
return order # 直接返回空列表
row, column = len(matrix), len(matrix[0]) # 根据矩阵的尺寸取到长和宽
left, right, up, down = 0, column-1, 0, row-1 # 定义上下左右的索引
if row == 1: # 如果只有一行的话,直接按照顺序返回即可,这一步可以没有
for _ in range(column): # 考虑清楚是row 还是 column
order.append(matrix[0][_])
return order
# 关于是否等于的情况,这里可以取等于的情况,如果不取等于,那么奇数行或者列剩下最后一行/列的时候,
# 就会因为无法取到相同的up down或者left/right,从而导致退出遍历,缺少一行
# 是否等于的情况不通用
# eg:不取等于的话,
# 输入:
# [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
# 输出:
# [1,2,3,4,8,12,11,10,9,5,7]
# 预期结果:
# [1,2,3,4,8,12,11,10,9,5,6,7]
while left <= right and up <= down:
for _ in range(left, right): # 开始进行遍历
order.append(matrix[up][_])
if len(order) == row * column: # 这里选择每一步都测试一order的长度是否已经等于矩阵的长宽了,只要等于,随时撤出。这样做避免了很多麻烦
return order
for _ in range(up, down):
order.append(matrix[_][right])
if len(order) == row * column: # 这里选择每一步都测试一order的长度是否已经等于矩阵的长宽了,只要等于,随时撤出
return order
for _ in range(right, left, -1): # 易错点:注意range的写法:取值范围,正取还是逆取
order.append(matrix[down][_])
if len(order) == row * column: # 这里选择每一步都测试一order的长度是否已经等于矩阵的长宽了,只要等于,随时撤出
return order
for _ in range(down, up, -1):
order.append(matrix[_][left])
if len(order) == row * column: # 这里选择每一步都测试一order的长度是否已经等于矩阵的长宽了,只要等于,随时撤出
return order
left += 1 # 考虑缩进,于while的关系:必须归属于while,不归属的话,执行完所有for循环就不干了
right -= 1
up += 1
down -= 1
# if row*column != len(order):
# order.append(matrix[][])
# 下面两行可加可不加
if len(order) == row * column:
return order
# 如果没有这一步,导致的结果是
# 输入:
# [[1,2,3],[4,5,6],[7,8,9]]
# 输出:
# [1,2,3,6,9,8,7,4]
# 预期结果:
# [1,2,3,6,9,8,7,4,5]
# 即行和列都是奇数的情况下,最后一个空填不出来,所以下面用and也行,只针对行列同时都是奇数的情况
if row % 2 and column % 2: # 只要循环结束,一直没有满足len(order) == row * column的条件,就到了这一步
order.append(matrix[row // 2][column // 2]) # 这个奇数偶数很有意思,类比行数是奇数会有问题,列数是偶数反而不用补充
return order
简化版代码
# 简化版的代码 最最最好简单易懂
class Solution:
def spiralOrder(self, matrix: list[list[int]]) -> list[int]:
order = list()
row, column = len(matrix), len(matrix[0])
left, right, up, down = 0, column-1, 0, row-1
while left <= right and up <= down:
for _ in range(left, right):
order.append(matrix[up][_])
if len(order) == row * column:
return order
for _ in range(up, down):
order.append(matrix[_][right])
if len(order) == row * column:
return order
for _ in range(right, left, -1):
order.append(matrix[down][_])
if len(order) == row * column:
return order
for _ in range(down, up, -1):
order.append(matrix[_][left])
if len(order) == row * column:
return order
left, right, up, down = left +1, right - 1, up + 1, down - 1
if row % 2 and column % 2:
order.append(matrix[row // 2][column // 2])
return order