重新开始刷算法题了,在这记录一些题型的解法
1.回溯问题
1.1数独问题
解题思路
首先构建一个检查函数,传入当前的数独矩阵以及需要检查的位置,返回需要尝试的数字集合 num_choice
将需要填写的位置全部存入集合中
构建递归函数
输入是位置列表以及当前填写的数独矩阵
1.如果待填为空,表示已经完成,返回True
2.获取第一个需要填写的位置的可能的数字集合,如果为空表示填写失败,返回上一级
3.对数字集合中的每一个数字尝试填入数独矩阵,并递归调用填写下一个
如果返回为True 表示后续填写成功,则向上返回True
返回False或者None时,表示失败,尝试下一个数字,此时需要恢复刚刚修改的数独矩阵数字
board =
[[".",".","9","7","4","8",".",".","."],
["7",".",".",".",".",".",".",".","."],
[".","2",".","1",".","9",".",".","."],
[".",".","7",".",".",".","2","4","."],
[".","6","4",".","1",".","5","9","."],
[".","9","8",".",".",".","3",".","."],
[".",".",".","8",".","3",".","2","."],
[".",".",".",".",".",".",".",".","6"],
[".",".",".","2","7","5","9",".","."]]
def check(b, x, y):
# 传入当前的结果矩阵以及坐标,返回可以选择的结果集
ret = set()
for _ in range(9):
if b[x][_] != '.':
ret.add(b[x][_])
if b[_][y] != '.':
ret.add(b[_][y])
i = x // 3
j = y // 3
for x1 in range(3):
for y1 in range(3):
if b[x1 + 3 * i][y1 + 3 * j] != '.':
ret.add(b[x1 + 3 * i][y1 + 3 * j])
return {'1', '2', '3', '4', '5', '6', '7', '8', '9'} - ret
lst = []
for i in range(9):
for j in range(9):
if board[i][j] == '.':
lst.append((i,j))
def get_num(b,lst):
if not lst:
return True
x,y = lst[0]
num_choice = check(b,x,y)
if not num_choice:
return False
for num in num_choice:
b[x][y] = num
if get_num(b,lst[1:]):
return True
b[x][y] = '.'
get_num(board,lst)
print(board)