編寫一個程式,求解數獨(Sudoku)問題。
數獨需要根據以下規則完成:
1-9
,且不能重複。1-9
,且不能重複。1-9
,且不能重複。注意:
'.'
表示。範例 1
輸入:
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"]]
輸出:
[["5","3","4","6","7","8","9","1","2"]
,["6","7","2","1","9","5","3","4","8"]
,["1","9","8","3","4","2","5","6","7"]
,["8","5","9","7","6","1","4","2","3"]
,["4","2","6","8","5","3","7","9","1"]
,["7","1","3","9","2","4","8","5","6"]
,["9","6","1","5","3","7","2","8","4"]
,["2","8","7","4","1","9","6","3","5"]
,["3","4","5","2","8","6","1","7","9"]]
回溯法(Backtracking),這是一種暴力解法。具體步驟如下:
.
)。1-9
填入這個位置,並檢查是否符合數獨規則。class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
def is_valid(board, row, col, num):
num = str(num)
# 檢查行
for i in range(9):
if board[row][i] == num:
return False
# 檢查列
for i in range(9):
if board[i][col] == num:
return False
# 檢查子方格
box_row_start = (row // 3) * 3
box_col_start = (col // 3) * 3
for i in range(box_row_start, box_row_start + 3):
for j in range(box_col_start, box_col_start + 3):
if board[i][j] == num:
return False
return True
def backtrack(board):
for i in range(9):
for j in range(9):
if board[i][j] == '.':
for num in range(1, 10):
if is_valid(board, i, j, num):
board[i][j] = str(num)
if backtrack(board):
return True
# 回溯
board[i][j] = '.'
return False
return True
backtrack(board)
is_valid
函數:backtrack
函數:1-9
,並遞歸解決。n
是空格數量。我們可以通過額外的資料結構來加速檢查行、列和子方格是否有重複數字:
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
rows = [set() for _ in range(9)]
cols = [set() for _ in range(9)]
boxes = [set() for _ in range(9)]
# 初始化集合
for i in range(9):
for j in range(9):
if board[i][j] != '.':
num = board[i][j]
rows[i].add(num)
cols[j].add(num)
boxes[(i // 3) * 3 + j // 3].add(num)
def backtrack(board):
for i in range(9):
for j in range(9):
if board[i][j] == '.':
for num in map(str, range(1, 10)):
box_index = (i // 3) * 3 + j // 3
if num not in rows[i] and num not in cols[j] and num not in boxes[box_index]:
# 填入數字
board[i][j] = num
rows[i].add(num)
cols[j].add(num)
boxes[box_index].add(num)
if backtrack(board):
return True
# 回溯
board[i][j] = '.'
rows[i].remove(num)
cols[j].remove(num)
boxes[box_index].remove(num)
return False
return True
backtrack(board)
n
是空格數量。