这道题是一道数独结题,是36题的延伸。
考点一:需要有三个集合分别存储每行、每列、每个小九宫格已经存在的数字供后续判断是否要填充
考点二:判断有效性,需要有一个函数判断填充的数字是否有效,影响范围只有上述三个字典,因此需要遍历0~9,找到和三个字典里的数字不冲突的第一个数字即可。(找到第一个合适的就可以,不用考虑是否会对其他位置的数字有影响)
考点三:提升性能学会使用递归
上代码:
import collections
class Solution(object):
def solveSudoku(self, board):
N = len(board)
rows = collections.defaultdict(set)
cols = collections.defaultdict(set)
boxes = collections.defaultdict(set)
for r in range(N):
for c in range(N):
if board[r][c] != '.':
val = int(board[r][c])
rows[r].add(val)
cols[c].add(val)
boxes[(r/3, c/3)].add(val)
def is_valid(r, c, val):
return val not in rows[r] and val not in cols[c] and val not in boxes[(r/3,c/3)]
def backtrack(r, c):
if r == N-1 and c == N:
return True
if c == N:
return backtrack(r+1, 0)
if board[r][c] != '.':
return backtrack(r, c+1)
for val in range(1, 10):
if is_valid(r, c, val):
board[r][c] = str(val)
rows[r].add(val)
cols[c].add(val)
boxes[(r/3, c/3)].add(val)
if backtrack(r, c+1): return True
else:
board[r][c] = '.'
rows[r].remove(val)
cols[c].remove(val)
boxes[(r/3, c/3)].remove(val)
return False
backtrack(0, 0)