【力扣-37】递归与回溯 python解题思路

力扣-37-递归与回溯 python解题思路

本文代码使用回溯,用于记录个人编写回溯的思路
代码思路看注释即可

力扣37

题目:力扣37解数独
相关题目:力扣36有效的数独,两题相关,可先看链接中的文章

# 注意:调用class中的函数或者数组都是使用self.的格式调用
# 提醒自己,别丢冒号
class Solution:
	# 设置数组,用于记录数独数字使用情况
	# 详细可见力扣36的思路
    def __init__(self):
        self.row = [[0] * 9 for _ in range(9)]
        self.col = [[0] * 9 for _ in range(9)]
        self.block = [[0] * 9 for _ in range(9)]
    
    # 回溯函数,简单粗暴地命名为huisu
    def huisu(self, i, j, board):
    	# i的范围是0-8,为 9时说明已经为数独找到解
        if i == 9:
            return True
        # j的范围同样是0-8,为 9就切换到下一行
        if j == 9:
            return self.huisu(i + 1, 0, board)
        # 先找到非空的数独格子
        if board[i][j] != ".":
            return self.huisu(i, j + 1, board)
        # b可以根据i,j求出,不用传递,节省开销
        b = (i // 3) * 3 + (j // 3)
       	# 数独中只能填入1-9的值,遍历0-8,包含8,填入数独时加1即可
        for s in range(9):
        	# 该数字不可用
        	# 可能是与同一行或者同一列或者同一格产生冲突
            if self.row[i][s] or self.col[j][s] or self.block[b][s]:
                continue
            else:
                self.row[i][s] = self.col[j][s] = self.block[b][s] = 1
                board[i][j] = str(s + 1)
                # 当前格子已经找到适合的数组
                # 递归点:下一个格子是否返回True依赖于下一个的下一个格子
                # 递归到最后是直到成功为最后一个格子找到合适的数字中间所有huisu return 1
                if self.huisu(i, j + 1, board):
                    return True
                # 回溯点:下一个格子没有找到合适的数字
                # 还原borad和self中的辅助数组
                else:
                    board[i][j] = '.'
                    self.row[i][s] = self.col[j][s] = self.block[b][s] = 0
        return False

    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        for i in range(9):
            for j in range(9):
                if board[i][j] == ".":
                    continue
                b = (i // 3) * 3 + (j // 3)
                num = int(board[i][j]) - 1
                self.row[i][num] = self.col[j][num] = self.block[b][num] = 1

        self.huisu(0, 0, board)
        return board

递归与回溯

写递归与回溯时需要想到起点和终点,当前题目中的起点是第一个格子,终点是最后一个格子
然后需要考虑回溯点和递归点,在我个人的理解中就是失败与成功
当前题目中:

  1. 回溯点是无法找到合适的数字,需要还原环境
  2. 递归点是能找到合适的数字,需要进入下一步

根据回溯点和递归点,得到一个结构:

if 当前节点成功:
	if 下一节点成功:
		return True
	# 下一节点失败
	else:
		还原环境,撤销当前节点的设置

那如何确保当前节点的设置不会重复执行呢?

# 思路为单向遍历, 不可回头
for item in range(9):
	if item符合当前节点要求:
		当前节点成功
	# 当前节点成功后的结果要么是 return True 结束当前节点
	# 要么是还原环境,所以直接continue 而不是 else continue
	continue
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值