37. 解数独
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
- 数字
1-9
在每一行只能出现一次。
- 数字
1-9
在每一列只能出现一次。
- 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用
'.'
表示。示例:

输入: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"]] 解释:输入的数独如上图所示,唯一有效的解决方案如下所示:

提示:
board.length == 9
board[i].length == 9
board[i][j]
是一位数字或者'.'
- 题目数据 保证 输入数独仅有一个解
通过次数97,273提交次数145,034
回溯
思路
其实就是把选择路径范围扩大到二维了,其他的没什么区别
题解
class Solution: def solveSudoku(self, board: List[List[str]]) -> None: """ Do not return anything, modify board in-place instead. """ def backtrack(board): for i in range(len(board)): #遍历行 for j in range(len(board[0])): #遍历列 if board[i][j] != ".": continue for k in range(1,10): #(i, j) 这个位置放k是否合适 if isValid(i,j,k,board): board[i][j] = str(k) #放置k if backtrack(board): return True #如果找到合适一组立刻返回 board[i][j] = "." #回溯,撤销k return False #9个数都试完了,都不行,那么就返回false return True #遍历完没有返回false,说明找到了合适棋盘位置了 def isValid(row,col,val,board): for i in range(9): #判断行里是否重复 if board[row][i] == str(val): return False for j in range(9): #判断列里是否重复 if board[j][col] == str(val): return False startRow = (row // 3) * 3 startcol = (col // 3) * 3 for i in range(startRow,startRow + 3): #判断9方格里是否重复 for j in range(startcol,startcol + 3): if board[i][j] == str(val): return False return True backtrack(board)
可以不用专门封装这个函数的,如下:
class Solution: def solveSudoku(self, board: List[List[str]]) -> None: """ Do not return anything, modify board in-place instead. """ for i in range(len(board)): for j in range(len(board[0])): if board[i][j] == ".": for k in range(1,10): if self.isValid(i,j,k,board): board[i][j] = str(k) if self.solveSudoku(board): return True board[i][j] = "." return False return True def isValid(self, row,col,val,board): for i in range(9): #判断行里是否重复 if board[row][i] == str(val): return False for j in range(9): #判断列里是否重复 if board[j][col] == str(val): return False startRow = (row // 3) * 3 startcol = (col // 3) * 3 for i in range(startRow,startRow + 3): #判断9方格里是否重复 for j in range(startcol,startcol + 3): if board[i][j] == str(val): return False return True