【回溯】leetcode37.解数独

461 篇文章 1 订阅

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

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

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
在这里插入图片描述
在这里插入图片描述
思路:
回溯

解答:
方法一:回溯

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        
        def isValid(row,col,val,board):
            n=len(board)
            #判断列
            for i in range(n):
                if board[row][i]==str(val):
                    return False
            #判断行
            for i in range(n):
                if board[i][col]==str(val):
                    return False
            #判断小格子
            row=(row//3)*3
            col=(col//3)*3
            for i in range(row,row+3):
                for j in range(col,col+3):   
                    if board[i][j]==str(val):
                        return False
            return True
            

        def tracebacking(board):
            n=len(board)
            for i in range(n):
                for j in range(n):
                    if board[i][j]!='.':
                        continue
                    #填数
                    for k in range(1,10):
                        if isValid(i,j,k,board):
                            board[i][j]=str(k)
                            #找到即返回
                            if tracebacking(board):
                                return True
                            board[i][j]='.'
                    return False
            return True    
        
        tracebacking(board)

方法二:原始解法

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        #按行进行遍历
        def dfs(board,x,y):
            if y==9:
                return dfs(board,x+1,0)
            if x==9:
                return True
            if board[x][y]!='.':
                return dfs(board,x,y+1)
            #为board[x][y]填值
            for i in range(9):
                if (not row[x][i]) and (not col[y][i]) and (not box[x//3][y//3][i]):
                    board[x][y]=str(i+1)
                    row[x][i],col[y][i],box[x//3][y//3][i]=1,1,1
                    if dfs(board,x,y+1):
                        break
                    #board[x][y]回退到初始状态,尝试下一个值
                    else:
                        board[x][y]='.'
                        row[x][i],col[y][i],box[x//3][y//3][i]=0,0,0
            return board[x][y]!='.'
            
        row=[[0]*9 for i in range(9)]
        col=[[0]*9 for i in range(9)]
        box=[[[0]*9 for _ in range(3)] for _ in range(3)]
        
        for i in range(9):
            for j in range(9):
                if board[i][j]!='.':
                    t=int(board[i][j])-1
                    row[i][t],col[j][t],box[i//3][j//3][t]=1,1,1
           
        dfs(board,0,0)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值