【Leetcode题解】37. 解数独(预处理+DFS)

Leetcode题解
题目链接: 37. 解数独
难度: 困难
解题思路: 一道很明显的搜索题,用DFS来求解。但是需要对数据进行预处理。记录一下某个为被覆盖的点的行、列、3*3方块内的所有备选值。可以很有效的减少搜索次数。逻辑很简单,详见代码。
题解:

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        SIZE = 9

        # 预处理,找到所有的行 列  方块的备选值
        row_candidate = []
        col_candidate = []
        cube_candidate = []
        visit_number = 0       # 表示未被填的空的数量
        position = [] # 未被填空的位置

        # 行
        for i in range(SIZE):
            candidate = [str(itera + 1) for itera in range(SIZE) ]
            for j in range(SIZE):
                if board[i][j] != '.':
                    candidate.remove(board[i][j])
            row_candidate.append(candidate)
        
        # 列
        for i in range(SIZE):
            candidate = [str(itera + 1) for itera in range(SIZE) ]
            for j in range(SIZE):
                if board[j][i] != '.':
                    candidate.remove(board[j][i])
            col_candidate.append(candidate)

        # 方块
        for i in range(SIZE):
            candidate = [str(itera + 1) for itera in range(SIZE) ]
            for j in range(SIZE):
                true_i = (i // 3) * 3 + j // 3
                true_j = (i % 3) * 3 + j % 3
                if board[true_i][true_j] != '.':
                    candidate.remove(board[true_i][true_j])
                else:
                    visit_number += 1
                    position.append([true_i, true_j])
            cube_candidate.append(candidate)
        
        # 结束标志
        self.res = False

        # dfs
        def dfs(i, roc = row_candidate, coc = col_candidate, cuc = cube_candidate):
            visit = []
            if visit_number == i:
                print("board = ", board)
                self.res = True
                # board = tboard # 最后的结果
                return 

            # 三种备选值的位置
            roc_index = position[i][0]
            coc_index = position[i][1]
            cuc_index = (position[i][0]//3 ) * 3 + position[i][1] // 3

            # 去掉相同的值
            temp_set = set(roc[roc_index]) & set(coc[coc_index]) & set(cuc[cuc_index])
            # print(temp_set)

            for ts in temp_set:
                if self.res:
                    return
                if ts in visit:
                    continue
                # 标记
                visit.append(ts)
                board[position[i][0]][position[i][1]] = ts
                roc[roc_index].remove(ts)
                coc[coc_index].remove(ts)
                cuc[cuc_index].remove(ts)

                dfs(i + 1, roc, coc, cuc)
				
				# 还原标记
                visit.remove(ts)
                roc[roc_index].append(ts)
                coc[coc_index].append(ts)
                cuc[cuc_index].append(ts)
        # dfs遍历每个未被覆盖的点       
        dfs(0)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值