這道題是一道數獨結題,是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)