37.Sudoku Solver

这道题是一道数独结题,是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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章