leetcode 37. Sudoku Solver 数独

思路

这是第一个自己解出来的Hard。用N皇后的递归思路,扫每一个空格,遍历1-9看可以放哪个数字,如果都不能放就清理现场回到上一层递归继续遍历。后来参考别人的思路,模拟人解题,先找出每个位置可以填的候选数,按照可填候选数的数目排序,从最少的开始填,这样剪枝掉一些不必要的计算。

代码

class Solution:
    def isValidPosition(self, n, row, col, board):
        for i in range(9):
            if board[row][i] == n:
                return False
            if board[i][col] == n:
                return False
            if board[3 * (row // 3) + i // 3][3 * (col // 3) + i % 3] == n:
                return False
        return True

    def solveSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        blank = []
        for i in range(9):
            for j in range(9):
                if board[i][j] == '.':
                    valid_digit = []
                    for n in [chr(x) for x in range(49, 58)]:
                        if self.isValidPosition(n, i, j, board):
                            valid_digit.append(n)
                    blank.append((i, j, valid_digit))
        blank.sort(key=lambda x: len(x[2]))
        self.flag = 0

        def fill(pos, board):
            if pos == len(blank):
                self.flag = 1
                return
            for n in blank[pos][2]:
                if len(blank[pos][2]) == 1:
                    board[blank[pos][0]][blank[pos][1]] = n
                    fill(pos + 1, board)
                else:
                    if self.isValidPosition(n, blank[pos][0], blank[pos][1], board):
                        board[blank[pos][0]][blank[pos][1]] = n
                        fill(pos + 1, board)
                        if self.flag == 1:
                            break
                        board[blank[pos][0]][blank[pos][1]] = '.'

        fill(0, board)

猜你喜欢

转载自blog.csdn.net/qq_35753140/article/details/84929119