题目
编写一个程序,通过已填充的空格来解决数独问题。
链接:https://leetcode.com/problems/sudoku-solver/
Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:
- Each of the digits 1-9 must occur exactly once in each row.
- Each of the digits 1-9 must occur exactly once in each column.
- Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.
Empty cells are indicated by the character ‘.’.
Example:
思路及代码
DFS
- 创建三个数组row,col,box分别记录每一行,每一列,每一个3x3的box中已经用过的数字,用过的标记为1,没用过的位置标记为0
- 比如row[5][4] = 1表示第6行数字4已经被用过了
- 先遍历一遍记录下所有已知的数字,然后继续遍历填充未知数字
- 对每一个未知数,遍历所有可能的选择,每次填充一个,然后继续填充下一个格子,如果有格子没有填充并且找不到可以用的数字则返回False,前面的格子就会继续尝试下一个可能性,直到找到解为止
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
# 9行1-9数字
row = [[0 for i in range(10)] for i in range(9)]
col = [[0 for i in range(10)] for i in range(9)]
box = [[0 for i in range(10)] for i in range(9)]
# 遍历一遍并记录所有已知数
for i in range(9):
for j in range(9):
if board[i][j] != '.':
row[i][int(board[i][j])] = 1
col[j][int(board[i][j])] = 1
box[i//3*3 + j//3][int(board[i][j])] = 1
def fill(x, y):
if x == 9 or y == 9:
return True
# 下一个x,下一个y
ny = (y + 1) % 9
nx = x + 1 if ny == 0 else x
# 如果已经有值,则直接继续下一个
if board[x][y] != ".":
return fill(nx, ny)
# 遍历限制条件并尝试赋值
for i in range(1, 10):
if not row[x][i] and not col[y][i] and not box[x//3*3 + y//3][i]:
row[x][i] = 1
col[y][i] = 1
box[x//3*3 + y//3][i] = 1
board[x][y] = str(i)
# 继续赋值下一个元素,直到每一个位置都赋上值
# 如果失败则返回重新尝试赋值下一个数字
if fill(nx, ny):
return True
row[x][i] = 0
col[y][i] = 0
box[x//3*3 + y//3][i] = 0
board[x][y] = '.'
return False
fill(0, 0)