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)

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