数独的问题

(1)从第一个空格开始。依次尝试1到9的数字,如果数字与盘面冲突就换成下一个数字,如果不冲突就去往第二个空格。

(2)在第二个空格,同样依次尝试1到9的数字,如果与盘面冲突就换成下一个数字,如果不冲突就去往第三个空格,以此类推。

(3)如果当前空格1到9的数字都填不了,就返回到上一个空格,再依次尝试没有试过的数字,如果与盘面冲突就换成下一个数字,如果不冲突就去往下一个空格。

(4)当最后一个空格被成功填上数字时,将答案加入答案列表。

(5)如果第一个空格填1到9都不成立,那么问题肯定没有解,在这种情况下返回的结果列表为空。

数独和N皇后十分相似,也是一个“前进—后退—前进—后退”的过程,只不过N皇后是一行一行地尝试,而数独是一个空格一个空格地尝试

需要记录当前空格的坐标,用于改变盘面中的数字。所以用一个数字变量表示。如图所示,第1格的index是0,第2格的index是1,第80格的index是79,第81格的index是80。如果给定一个坐标,比如55,通过除以9并取余数,商为6,余数为1,就能得知55代表的是第7行的第2个数.

代码

import copy


# 输出board所有的答案
def sudoku(board):
    # 检查当前数字在盘面中是否成立
    # i是当前行,j是当前列,num是当前数字
    def checkBoard(i, j, num):
        for t in range(9):
            if t != j and board[i][t] == num:  # 检查行
                return False
            if t != i and board[t][j] == num:  # 检查列
                return False

        for t in range(i - i % 3, 3 + i - i % 3):  # 检查3×3区域
            for s in range(j - j % 3, 3 + j - j % 3):
                if t != i and s != j and board[t][s] == num:
                    return False
        return True

    # 填满盘面中第index格到最后一个格
    def helper(index):
        if index == 81:  # 边界条件
            solution = copy.deepcopy(board)  # 深度复制当前盘面,放到res列表里
            res.append(solution)
            return  # 返回到上一次被调用的地方(第80个空格)
        i = index // 9  # 当前行
        j = index % 9  # 当前列
        if board[i][j] == 0:  # 如果当前格没有已知数字
            for num in range(1, 10):  # 依次尝试1~9
                board[i][j] = num
                if checkBoard(i, j, num):
                    helper(index + 1)  # 去往下一个空格
                board[i][j] = 0  # 将空格重新变空
        else:  # 如果当前格是盘面自带的数字
            helper(index + 1)

    res = []
    helper(0)  # 从第一个空格开始
    return res

注意1:如果直接res.append(board)的话,被复制的是指向board的指针,而不是当前board的数值。

注意2:当1~9都不可行时,这时当前格里的数字是9。接着会退回到上一格尝试下一个数字。这时checkBoard会返回False,但当前格的9没有被清除。这并不是期望看到的,因此需要加上board[i]​[j]=0。

输入:

matrix = [[5, 3, 0, 0, 7, 0, 0, 0, 0],
          [6, 0, 0, 1, 9, 5, 0, 0, 0],
          [0, 9, 8, 0, 0, 0, 0, 6, 0],
          [8, 0, 0, 0, 6, 0, 0, 0, 3],
          [4, 0, 0, 8, 0, 3, 0, 0, 1],
          [7, 0, 0, 0, 2, 0, 0, 0, 6],
          [0, 6, 0, 0, 0, 0, 2, 8, 0],
          [0, 0, 0, 4, 1, 9, 0, 0, 5],
          [0, 0, 0, 0, 8, 0, 0, 7, 9]]
result = sudoku(matrix)

输出:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

algorithm6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值