Leetcode037 sudoku-solver

解数独

题目描述:

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则

  1. 数字 1-9 在每一行只能出现一次。

  2. 数字 1-9 在每一列只能出现一次。

  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

空白格用 '.' 表示。

Leetcode037 sudoku-solver_第1张图片

一个数独。


Leetcode037 sudoku-solver_第2张图片

答案被标成红色。

Note:

  • 给定的数独序列只包含数字 1-9 和字符 '.'
  • 你可以假设给定的数独只有唯一解。
  • 给定数独永远是 9x9 形式的。

解题思路:

利用分步验证和递归的方式解答

  • 本题主要利用了solver()函数进行填入数字的递归操作,利用isValue()函数来判断填入的数字是否满足题意。因为我们只能在原有矩阵中进行修改,所以只能返回True或者False来判断当前所填入的数字是否满足要求

  • 在函数solver()中,我们遍历每一个9x9矩阵的点,将1-9的数字依次填入,如果满足要求,就进行下一个位置的递归,如果不满足要求,就在该位置使用下一个数字进行递归(if self.isValue(board, i, j) and self.solver(board)),如果所有数字都不满足要求,则可能是上一次选择的数字不满足要求,就倒退回去,重新选择,同时将数字转为.board[i][j] = '.'

  • 在函数isValue()中,需要判断每一行,每一列,以及在每一个3x3小矩阵内是否满足要求,这里可以参考第36题解数独的方法


Python源码:

from typing import List


class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        self.solver(board)
    
    def isValue(self, board, x, y):
        # 检查填入的坐标是否与行中已有的元素相等
        for i in range(9):
            if i != x and board[i][y] == board[x][y]:
                return False
        # 检查行是否符合
        for j in range(9):
            if j != y and board[x][j] == board[x][y]:
                return False

        # 检查每个正方形是否符合
        m = 3 * (x // 3)
        n = 3 * (y // 3)
        for i in range(3):
            for j in range(3):
                if (i + m != x or j + n != y) and board[i + m][j + n] == board[x][y]:
                    return False
        return True

    def solver(self, board):
        # 遍历每一个坐标
        for i in range(9):
            for j in range(9):
                # 找board里的需要填入的位置
                if board[i][j] == '.':
                    for k in '123456789':
                        board[i][j] = k
                        # 在if的时候调用递归
                        if self.isValue(board, i, j) and self.solver(board):
                            return True
                        # 到这个位置说明填入的数不太行,所以先空着
                        board[i][j] = '.'
                    # 进行完当前可选的所有数字都不行,说明上一次决策有问题,返回false

                    return False
        return True

        

欢迎关注我的github:https://github.com/UESTCYangHR

你可能感兴趣的:(Leetcode037 sudoku-solver)