《代码随想录》学习笔记,原链接:https://programmercarl.com/
59.螺旋矩阵II
(1)循环不变量原则
模拟顺时针画矩阵的过程,由外向内顺时针一圈一圈这么画下去。这里一圈下来,要画每四条边,每画一条边都要坚持一致的左闭右开,这样这一圈才能按照统一的规则画下来。左开右闭,如图下所示:
(2)核心代码模式
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
startX, startY = 0, 0
matrix = [[0] * n for i in range(n)] # 初始化一个n * n长度的列表
i, j, counter = 0, 0, 1
loop = n // 2
for offset in range(1, loop + 1) : # 根据圈数确定偏移量
for j in range(startX, n - offset): # 当n = 3时,结束循环后j的值为1
matrix[i][j] = counter
counter += 1
for i in range(startY, n - offset): # 当n = 3时,结束循环后i的值为1
matrix[i][j + 1] = counter
counter += 1
for j in range(n - offset, startX, -1): # 倒序遍历数字, 当n = 3时,结束循环后j的值为1
matrix[i + 1][j] = counter
counter += 1
for i in range(n - offset, startY, -1): # 倒序遍历数字, 当n = 3时,结束循环后i的值为1
matrix[i][j - 1] = counter
counter += 1
startX += 1
startY += 1
if n % 2 != 0: # 如果n为奇数,补全最中心的空缺部分
matrix[i][j] = counter
return matrix
【注1】矩阵的行号i,列号j,图像的横坐标x,纵坐标y之间的关系:
- 用i来表示矩阵元素(图像像素)的行号,j表示矩阵元素(图像像素)的列号
- 用x来表示矩阵元素(图像像素)的横坐标,y来表示矩阵元素(图像像素)的纵坐标
所以,(x,y)=(j,i)
一般循环体中用变量i,j,具体元素坐标用x,y。
【注2】统计矩阵的行和列大小:
(3) ACM模式
class Solution:
def generateMatrix(self, n):
startX, startY = 0, 0
matrix = [[0] * n for i in range(n)] # 初始化一个n * n长度的列表
i, j, counter = 0, 0, 1
loop = n // 2
for offset in range(1, loop + 1): # 根据圈数确定偏移量
for j in range(startX, n - offset): # 当n = 3时,结束循环后j的值为1
matrix[i][j] = counter
counter += 1
for i in range(startY, n - offset): # 当n = 3时,结束循环后i的值为1
matrix[i][j + 1] = counter
counter += 1
for j in range(n - offset, startX, -1): # 倒序遍历数字, 当n = 3时,结束循环后j的值为1
matrix[i + 1][j] = counter
counter += 1
for i in range(n - offset, startY, -1): # 倒序遍历数字, 当n = 3时,结束循环后i的值为1
matrix[i][j - 1] = counter
counter += 1
startX += 1
startY += 1
if n % 2 != 0: # 如果n为奇数,补全最中心的空缺部分
matrix[i][j] = counter
return matrix
# 确定矩阵的行数和列数
n = int(input("输入矩阵的行数和列数n:"))
# 螺旋矩阵II
solution = Solution()
result = solution.generateMatrix(n)
print(result)
螺旋矩阵相关题目
(1)54.螺旋矩阵
- 核心代码模式
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
startX, startY = 0, 0
m = int(len(matrix)) # 计算矩阵的行数m
n = int(len(matrix[0])) # 计算矩阵的列数n,由于要作为循环不变量,因此要将其化为int型
loop = min(m, n) // 2
numberList = [0 for i in range(m * n)] # 构建长度为m*n的列表
i, j = 0, 0
counter = 0
# 循环不变量,左闭右开
for offset in range(1, loop + 1):
for j in range(startX, n - offset):
numberList[counter] = matrix[i][j]
counter += 1
for i in range(startY, m - offset):
numberList[counter] = matrix[i][j + 1]
counter += 1
for j in range(n - offset, startX, -1): # 注意要加-1,表示反向移动
numberList[counter] = matrix[i + 1][j]
counter += 1
for i in range(m - offset, startY, -1):
numberList[counter] = matrix[i][j - 1]
counter += 1
startX += 1
startY += 1
if min(m, n) % 2 != 0: # 补充循环部分没有取到的元素
if m < n:
for j in range(startY, startY + n - m + 1):
numberList[counter] = matrix[i][j]
counter += 1
else:
for i in range(startX, startX + m - n + 1):
numberList[counter] = matrix[i][j]
counter += 1
return numberList
- ACM模式
class Solution:
def spiralOrder(self, matrix):
startX, startY = 0, 0
m = int(len(matrix)) # 计算矩阵的行数m
n = int(len(matrix[0])) # 计算矩阵的列数n,由于要作为循环不变量,因此要将其化为int型
loop = min(m, n) // 2
numberList = [0 for i in range(m * n)] # 构建长度为m*n的列表
i, j = 0, 0
counter = 0
# 循环不变量,左闭右开
for offset in range(1, loop + 1):
for j in range(startX, n - offset):
numberList[counter] = matrix[i][j]
counter += 1
for i in range(startY, m - offset):
numberList[counter] = matrix[i][j + 1]
counter += 1
for j in range(n - offset, startX, -1): # 注意要加-1,表示反向移动
numberList[counter] = matrix[i + 1][j]
counter += 1
for i in range(m - offset, startY, -1):
numberList[counter] = matrix[i][j - 1]
counter += 1
startX += 1
startY += 1
if min(m, n) % 2 != 0: # 补充循环部分没有取到的元素
if m < n:
for j in range(startY, startY + n - m + 1):
numberList[counter] = matrix[i][j]
counter += 1
else:
for i in range(startX, startX + m - n + 1):
numberList[counter] = matrix[i][j]
counter += 1
return numberList
# 确定矩阵的行数和列数
m = int(input("输入矩阵的行数m:"))
n = int(input("输入矩阵的列数n:"))
# 输入矩阵
matrix = []
for i in range(0, m):
row = []
for j in range(0, n):
num = int(input("输入第{}行,第{}列的元素:".format(i +1, j + 1)))
row.append(num)
matrix.append(row)
print("输入的矩阵为:", matrix)
# 螺旋矩阵
solution = Solution()
result = solution.spiralOrder(matrix)
print(result)
(2)LCR 146.螺旋遍历二维数组
class Solution:
def spiralArray(self, array: List[List[int]]) -> List[int]:
startX, startY = 0, 0
nullList = []
m = int(len(array)) # 计算矩阵的行数m
if m == 0: # 原矩阵为空
return nullList
n = int(len(array[0])) # 计算矩阵的列数n,由于要作为循环不变量,因此要将其化为int型
loop = min(m, n) // 2
numberList = [0 for i in range(m * n)]
i, j = 0, 0
counter = 0
for offset in range(1, loop + 1):
for j in range(startX, n - offset):
numberList[counter] = array[i][j]
counter += 1
for i in range(startY, m - offset):
numberList[counter] = array[i][j + 1]
counter += 1
for j in range(n - offset, startX, -1): # 注意要加-1,表示反向移动
numberList[counter] = array[i + 1][j]
counter += 1
for i in range(m - offset, startY, -1):
numberList[counter] = array[i][j - 1]
counter += 1
startX += 1
startY += 1
if min(m, n) % 2 != 0: # 补充循环部分没有取到的元素
if m < n:
for j in range(startY, startY + n - m + 1):
numberList[counter] = array[i][j]
counter += 1
else:
for i in range(startX, startX + m - n + 1):
numberList[counter] = array[i][j]
counter += 1
return numberList