【9月打卡~Leetcode每日一题】37. 解数独(难度:困难)

37. 解数独
在这里插入图片描述
说实话,一开始看到这个题目的时候我是很拒绝的,因为感觉不确定性太大,然后去听了会歌,放松了一下心情,写下了第一版代码
在这里插入图片描述
维护3个数组+1个队列,数组分别存每行、每列、每单元格的数字情况
队列用于存储未填充的空白格
遍历数独,如果是空白,则加入visit队列,如果是数字,则在对应的三个数组中更新相应的信息。
在第一次中,我看通过率很高(事实证明是假的 )就直接用最简单的判断,如果该空白只有一个可以填的数字,那么填入这个数字并更新数组,因此超出时间限制了。

在第二版代码里用了枚举+回溯,
当递归到最后一个空白格后,如果仍然没有冲突,说明我们找到了答案;在递归的过程中,如果当前的空白格不能填下任何一个数字,那么就进行回溯。

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        rows = [[False]*9 for _ in range(9)] #行
        lines = [[False]*9 for _ in range(9)]#列
        cells = [[False]*9 for _ in range(9)]#格
        visit = []

        for i in range(9):
            for j in range(9):
                if board[i][j] == '.':
                    visit.append((i,j))
                else:
                    rows[i][int(board[i][j])-1] = True
                    lines[j][int(board[i][j])-1] = True
                    cells[j//3+3*(i//3)][int(board[i][j])-1] = True

        valid = False

        def dfs(pos):
            nonlocal valid
            if pos == len(visit):
                valid = True
                return
            x_,y_ = visit[pos]
            for i in range(9):
                if(rows[x_][i]==lines[y_][i]==cells[y_//3+3*(x_//3)][i]==False):
                    rows[x_][i]=lines[y_][i]=cells[y_//3+3*(x_//3)][i] = True
                    board[x_][y_] = str(i+1)
                    dfs(pos+1)
                    rows[x_][i]=lines[y_][i]=cells[y_//3+3*(x_//3)][i] = False
                if valid:
                    return

        dfs(0)

时间复杂度取决于给定的数组,复杂度上界为O(9^81)

甚至去挑战了一下高级+
在这里插入图片描述
枚举回溯永远滴神!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值