题目描述
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。
一个数独。
答案被标成红色。
Note:
给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。
解题思路
深度优先搜索。
当前位置上如果有数字,判断下一个位置,如果所有位置上都是数字,则是一个解,返回。
当前位置上有数字,判断下一个位置,如果下一个位置上没有数字,则根据数字1~9实验,满足题目的要求为止。
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
def isvalid(i,j,ch):
# 确保当前的数字ch放到位置(i,j)上之后满足题目要求。
for n in range(9):
if board[n][j] == ch : return False
if board[i][n] == ch: return False
if board[i//3* 3 + n//3][j//3*3+n%3] == ch: return False
return True
def dfs(i,j):
if board[i][j] != '.':
# 如果当前位置(i,j)上有数字,并且已经对所有81位置进行了检查
# 且都有数字,则说明解题完成。返回
# 如果没有检查完,j<8 列没查完,则从当前行的下一列开始检查
# 如果行没有检查完,i<8,则从下一行进行检查,因为每一行的起始列索引是0
# 所以j是0.
if i == 8 and j == 8:
self.flag = True
return
if j < 8:
return dfs(i,j+1)
else:
return dfs(i+1,0)
return
for ch in range(1,10):
ch = str(ch)
if isvalid(i,j,ch):
board[i][j] = ch
if i == 8 and j == 8:
self.flag = True
return
if j < 8:
dfs(i,j+1)
else:
dfs(i+1,0)
if self.flag:return
board[i][j] = '.'
self.flag = False
dfs(0,0)