59.螺旋矩阵II
# 59.螺旋矩阵II
# 参考
# class Solution:
#
# def generateMatrix(self, n: int) -> List[List[int]]:
# # 初始化要填充的正方形
# matrix = [[0] * n for _ in range(n)]
#
# left, right, up, down = 0, n - 1, 0, n - 1
# number = 1 # 要填充的数字
#
# while left < right and up < down:
#
# # 从左到右填充上边
# for x in range(left, right):
# matrix[up][x] = number
# number += 1
#
# # 从上到下填充右边
# for y in range(up, down):
# matrix[y][right] = number
# number += 1
#
# # 从右到左填充下边
# for x in range(right, left, -1):
# matrix[down][x] = number
# number += 1
#
# # 从下到上填充左边
# for y in range(down, up, -1):
# matrix[y][left] = number
# number += 1
#
# # 缩小要填充的范围
# left += 1
# right -= 1
# up += 1
# down -= 1
#
# # 如果阶数为奇数,额外填充一次中心
# if n % 2:
# matrix[n // 2][n // 2] = number
#
# return matrix
# 1.0 坚持一致性原则 左闭右开
class Solution:
def generateMatrix(self, n: int) -> list[list[int]]:
matrix = [[0 for _ in range(n)] for _ in range(n)]
left, right, up, down = 0, n-1, 0, n-1
number = 1
while left<=right and up<=right: # 为什么不取等于的情况?
# from left to right
for _ in range(left, right):
matrix[up][_] = number
number += 1
# from up to down
for _ in range(up, down):
matrix[_][right] = number
number += 1
# from right to left
for _ in range(right, left, -1):
matrix[down][_] = number
number += 1
# from down to up
for _ in range(down, up, -1):
matrix[_][left] = number
number += 1
left += 1
right -= 1
up += 1
down -= 1
if n % 2:
matrix[n // 2][n // 2] = number # //取整,返回商的整数部分
return matrix
54. 螺旋矩阵
# 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]:
# if not matrix or not matrix[0]:
# return list()
#
# rows, columns = len(matrix), len(matrix[0])
# order = list()
# left, right, top, bottom = 0, columns - 1, 0, rows - 1
# while left <= right and top <= bottom:
# for column in range(left, right + 1):
# order.append(matrix[top][column])
# for row in range(top + 1, bottom + 1):
# order.append(matrix[row][right])
# if left < right and top < bottom:
# for column in range(right - 1, left, -1):
# order.append(matrix[bottom][column])
# for row in range(bottom, top, -1):
# order.append(matrix[row][left])
# left, right, top, bottom = left + 1, right - 1, top + 1, bottom - 1
# return order
# 测试
# def spiralOrder(matrix: list[list[int]]) -> list[int]:
# order = list()
# # if not matrix or len(matrix) == 0:
# if not matrix or not matrix[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
#
# 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): # 易错点:注意range的写法:取值范围,正取还是逆取
# 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 += 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
# if row % 2 or column % 2:
# order.append(matrix[row // 2][column // 2]) # 这个奇数偶数很有意思,类比行数是奇数会有问题,列数是偶数反而不用补充
# return order
# print(spiralOrder([[1,2,3,4],[5,6,7,8],[9,10,11,12]]))
# 简化版的代码 最最最好简单易懂
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
Offer 29.顺时针打印矩阵
# 剑指Offer 29.顺时针打印矩阵
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]:
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
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): # 易错点:注意range的写法:取值范围,正取还是逆取
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 += 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
if row % 2 or column % 2:
order.append(matrix[row // 2][column // 2]) # 这个奇数偶数很有意思,类比行数是奇数会有问题,列数是偶数反而不用补充
return order