LC37. 解数独

求可用数字之后三个条件的交集解法

def solveSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: None Do not return anything, modify board in-place instead.
        """
        row = [set(range(1,10)) for _ in range(9)]    #用三个set分别记录行,列,块可用的数字
        col = [set(range(1,10)) for _ in range(9)]
        block = [set(range(1,10)) for _ in range(9)]
        todo = []                                     
        for i in range(9):
            for j in range(9):
                if board[i][j] != ".":                #如果已经填了
                    row[i].remove(int(board[i][j]))   #这一行不能用了
                    col[j].remove(int(board[i][j]))   #这一列不能用了
                    block[(i//3)*3+j//3].remove(int(board[i][j]))       #这一块也不能用了
                else:                                 #记录要填的位置
                    todo.append((i,j))
        def backtrack(n):
            if n == len(todo):                        #全部填完
                return True
            i,j = todo[n]                             #从第一个要填的位置开始填
            b = (i//3)*3+j//3
            for val in row[i]&col[j]&block[b]:        #这个位置所处的行,列,块剩余的可填数字。这里相当于把所有的都试一遍
                row[i].remove(val)
                col[j].remove(val)
                block[b].remove(val)
                board[i][j] = str(val)                #填这个数
                if backtrack(n+1):                    #如果n+1不行,那么回退重新试新的
                    return True
                row[i].add(val)                      
                col[j].add(val)
                block[b].add(val)
            return False                             #没填完,但是可以使用的数没了,说明前面填错了,回溯。
        backtrack(0)

常规回溯解法

def solveSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: None Do not return anything, modify board in-place instead.
        """
        def helper(board,r,c,k):
            for i in range(9):
                if board[r][i] == str(k):
                    return 0
            for j in range(9):
                if board[j][c] == str(k):
                    return 0 
            bi,bj = (r//3)*3,(c//3)*3
            for ii in range(bi,bi+3):
                for jj in range(bj,bj+3):
                    if board[ii][jj] == str(k):
                        return 0
            return 1
        def backtrack(board):
            for i in range(9):
                for j in range(9):
                    if board[i][j] == ".":
                        for k in range(1,10):
                            if helper(board,i,j,k) == 1:
                                board[i][j] = str(k)
                                if backtrack(board):
                                    return True
                                board[i][j] = "."
                        return False
            return True
        backtrack(board)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值