数独不仅是益智游戏,更是回溯算法的典范!本期我们将用 DFS + 剪枝 的方式一步步求解一个标准 9x9 数独。
给定一个部分填充的 9×9 数独棋盘,请编写一个程序将其填完,使每行、每列、每个 3×3 宫内的数字 1~9 均不重复。
board = [
["5","3",".",".","7",".",".",".","."],
["6",".",".","1","9","5",".",".","."],
[".","9","8",".",".",".",".","6","."],
["8",".",".",".","6",".",".",".","3"],
["4",".",".","8",".","3",".",".","1"],
["7",".",".",".","2",".",".",".","6"],
[".","6",".",".",".",".","2","8","."],
[".",".",".","4","1","9",".",".","5"],
[".",".",".",".","8",".",".","7","9"]
]
使用回溯 + 剪枝,依次尝试将数字 1~9 填入空格中,若不符合数独规则则回退重试。
def solve_sudoku(board):
def is_valid(r, c, ch):
for i in range(9):
if board[r][i] == ch or board[i][c] == ch:
return False
box_r, box_c = 3 * (r // 3) + i // 3, 3 * (c // 3) + i % 3
if board[box_r][box_c] == ch:
return False
return True
def dfs():
for i in range(9):
for j in range(9):
if board[i][j] == ".":
for ch in map(str, range(1, 10)):
if is_valid(i, j, ch):
board[i][j] = ch
if dfs():
return True
board[i][j] = "."
return False
return True
dfs()
solve_sudoku(board)
for row in board:
print(" ".join(row))
步骤 | 说明 |
---|---|
查找空位 | 使用双层循环寻找 . |
合法判断 | 检查当前行、列、宫格是否冲突 |
回溯回退 | 无法填充时,重置该位置为 . |
✅ 本题是典型的「排列填空 + 剪枝」模型
数独是一道优雅的全排列题目,透过回溯 + 剪枝,掌握“选择-尝试-回退”的算法核心!
下一期预告:单词搜索(网格回溯)
点个赞 + 收藏 ,学透回溯,从数独开始!