leetcode-------解数独(回溯法)

如:

方法:回溯法:

回溯法的思想就是:对于一个问题有多个选择方式,先选择一个方式执行下去,若在执行过程中,发现不符合规则,则回退,回到选择方式的步骤,进而选择其他方式,继续试。

重要:对于回溯法,一定会有个[规则],这个[规则]将会决定是否回退,所以当我们在使用回溯法时,一定要留意能否构建[规则]

如这一题,在数独中,规则就是:

1. 在同一列和同一行中,不能出现一样的数字。

2. 在同一个九宫格中,也不难出现同样的数字。

所以我们需要用代码构建规则:

def ok(self,board,i:int,j:int,x:str) -> bool:
        for t in range(9):
                if board[t][j] == x:return False  #(i,j)的同一列中是否已经出现x
                if board[i][t] == x:return False  #(i,j)的同一行中是否已经出现x
                if board[i//3* 3 + t//3][j//3*3 + t%3] == x: return False  #(i,j)的同一个九宫格中是否已经出现x
        return True  

然后我们进入进一步的讨论:

在回溯法中,我们需要构造一个[链式标签](这是我的说法),意思是:当当前有多种方式可以选择时,我们随机选一种,但并不清楚这种方式是否选得正确,所以当前状态的正确性是由接下去的步骤决定的,若在下面的步骤中,发现与现在的规则不相符,则表明上一步的选择是False的,所以回退到上一步骤,选择其他方式。 要想获得True,只有一种可能,就是程序能顺利执行到结束,所有的选择都与规则相符,才会返回True。否则中间只要有一步错了,就会返回False,一返回False就要回退重新选择。

那如果实现这种方式呢?答案是用递归。代码如下:

代码:

class Solution:
    def solveSudoku(self, board) -> None:
        self.sudoke(board,0,0)
    def sudoke(self,board,i:int,j:int):
        if j<=8: #若列没有越界
            if board[i][j] != ".": #当前位置若不为空,不需要填入数字,直接去下一个位置
                if i<8:  #若未到最后一行,则到下一行的位置
                    if(self.sudoke(board,i+1,j)):return True
                else:    #若已经是最后一行,则到下一列的起始位置
                    if(self.sudoke(board,0,j+1)):return True
                return False
            else:   #当前位置为空,需要填入数字
                for x in range(1,10):   #从1-9选数字填入空格
                    if not self.ok(board,i,j,str(x)):continue
                    board[i][j] = str(x)
                    if i<8:  #若未到最后一行,则到下一行的位置
                        if(self.sudoke(board,i+1,j)):return True
                    else:    #若已经是最后一行,则到下一列的起始位置
                        if(self.sudoke(board,0,j+1)):return True
                    board[i][j] = '.'   #若上诉步骤返回false,则清空当前位置填入的数字
                return False   #若1-9的9个数字都不符合填入规则,则返回False
        return True
    #判断条件:判断x能不能被填入
    def ok(self,board,i:int,j:int,x:str) -> bool:
        for t in range(9):
                if board[t][j] == x:return False  #(i,j)的同一列中是否已经出现x
                if board[i][t] == x:return False  #(i,j)的同一行中是否已经出现x
                if board[i//3* 3 + t//3][j//3*3 + t%3] == x: return False  #(i,j)的同一个九宫格中是否已经出现x
        return True  #若x符合填入条件,返回True。否则返回False

board = [['5','3','.','.','7','.','.','.','.'],
         ['6','.','.','1','9','5','.','.','.'],
         ['.','9','8','.','.','.','.','6','.'],
         ['8','.','.','.','6','.','.','.','3'],
         ['4','.','.','8','.','3','.','.','1'],
         ['7','.','.','.','2','.','.','.','6'],
         ['.','6','.','.','.','.','2','8','.'],
         ['.','.','.','4','1','9','.','.','5'],
         ['.','.','.','.','8','.','.','7','9']]
s = Solution()
s.solveSudoku(board)
for x in board:
    print(x)

运行效果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来决这个问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值