Leetcode练习(Python):哈希表类:第37题:解数独:编写一个程序,通过已填充的空格来解决数独问题。 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

题目:
解数独:编写一个程序,通过已填充的空格来解决数独问题。  一个数独的解法需遵循如下规则:  数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 空白格用 '.' 表示。  

思路:
这道题太难了,按照自己的思路从昨晚到现在了,实现不了,还是水平不够高吧,后来看了官方的解答,发现自己的思路一开始就设计错了,太难了,理解了一下官方的程序,然后放到这里了,以备继续学习,怀挺!
程序:
from collections import defaultdict
class Solution:
    def solveSudoku(self, board):
        def could_place(d, row, col):
            return not (d in rows[row] or d in columns[col] or 
                    d in boxes[box_index(row, col)])
        
        def place_number(d, row, col):
            rows[row][d] += 1
            columns[col][d] += 1
            boxes[box_index(row, col)][d] += 1
            board[row][col] = str(d)
            
        def remove_number(d, row, col):
            del rows[row][d]
            del columns[col][d]
            del boxes[box_index(row, col)][d]
            board[row][col] = '.'    
            
        def place_next_numbers(row, col):
            if col == N - 1 and row == N - 1:
                nonlocal sudoku_solved
                sudoku_solved = True
            else:
                if col == N - 1:
                    backtrack(row + 1, 0)
                else:
                    backtrack(row, col + 1)               
                
        def backtrack(row = 0, col = 0):
            if board[row][col] == '.':
                for d in range(1, 10):
                    if could_place(d, row, col):
                        place_number(d, row, col)
                        place_next_numbers(row, col)
                        if not sudoku_solved:
                            remove_number(d, row, col)
            else:
                place_next_numbers(row, col)
                    
        n = 3
        N = n * n
        box_index = lambda row, col: (row // n ) * n + col // n
        
        rows = [defaultdict(int) for i in range(N)]
        columns = [defaultdict(int) for i in range(N)]
        boxes = [defaultdict(int) for i in range(N)]
        for i in range(N):
            for j in range(N):
                if board[i][j] != '.': 
                    d = int(board[i][j])
                    place_number(d, i, j)
        
        sudoku_solved = False
        backtrack()
原文地址:https://www.cnblogs.com/zhuozige/p/12807463.html