回溯算法(3)--其实不是回溯 填充才会涉及到回溯

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

判断条件:

1.行内无重复 当前数字不能在同一行已出现过 使用一个数组row[i]记录第i行已经出现的数字 

2. 列内无重复 当前数字不能在同一列已出现过 使用一个数组cols[i]记录第i列已经出现的数字

3.3*3宫格内无重复  看下面的图 是将9*9的分为9个格子 所以我们可以给每一格格子一个编号 当一个元素出现在这个编号里面的时候 它就不能再出现第二次  box_id的计算公式为:box_id = (i // 3) * 3 + (j // 3)

回溯算法(3)--其实不是回溯 填充才会涉及到回溯_第1张图片

    这三个条件一旦有一个条件不满足 就直接return false 如果没有出现的话就加上去 如果已经在了 但是仍然又来一次 那么就false 代码如下

    class Solution(object):
     def isValidSudoku(self, board):
        # 初始化行、列、宫格的记录器
        rows = [list() for _ in range(9)]
        #创建9个空列表,每个列表对应数独的一行(共9行)比如说row[0]就是存储第一行的元素
        cols = [list() for _ in range(9)]
        boxes = [list() for _ in range(9)]  # 宫格索引公式: (i//3)*3 + j//3 编号为0-8
        #rows = [set() for _ in range(9)]
        for i in range(9):
            for j in range(9):
                num = board[i][j]
                if num == '.':
                    continue  # 跳过空
                # 检查三个条件
                if num in rows[i]:#第二次又来了 那么false 比如1已经在第一行出现了 那么就不能再在这个列表里面了
                    return False
                if num in cols[j]:
                    return False
                if num in boxes[(i // 3) * 3 + (j // 3)]:#已经在格子里了 又来了 false
                    return False
                # 记录数字
                rows[i].append(num)#第一次来给加上去 在对应的位置
                cols[j].append(num)
                boxes[(i // 3) * 3 + (j // 3)].append(num)
        return True  # 所有检查通过
    board = [["5","3",".",".","7",".",".",".","."]
    ,["6",".",".","1","9","5",".",".","."]
    ,[".","9","8",".",".",".",".","6","."]
    ,["8",".",".",".","6",".",".",".","3"]
    ,["4",".",".","8",".","3",".",".","1"]
    ,["7",".",".",".","2",".",".",".","6"]
    ,[".","6",".",".",".",".","2","1","."]
    ,[".",".",".","4","1","9",".",".","5"]
    ,[".",".",".",".","8",".",".","7","9"]]
    solution=Solution()
    result=solution.isValidSudoku(board)
    print(result)

    思路其实很明确 就是如果这个元素还没在这个行里面 加进去 在了 再来第二遍那就不行 只要有一个条件不满足那就不行 一旦这三个都满足 那么该加的都加好 继续检查下一个

    我用的是列表 但是使用集合是会更快的 就像是查找这个元素在不在集合里面的话 速度是o(1) 集合的天然语义与数独的不允许一行出现两个相同元素 相符合 代码可读性更强 

    回溯算法(3)--其实不是回溯 填充才会涉及到回溯_第2张图片rows[0] = {"3", "7", "2"}
    if "5" in rows[0]:  # 1次哈希计算 → O(1)

    rows[0] = ["3", "7", "2"]
    if "5" in rows[0]:  # 需要比较 "5"=="3"? "5"=="7"? "5"=="2"? → O(n)

    我接下来写一个文章针对于哈希表 与python常用的四大数据结构:列表 字典 集合  元组 

    这个代码不算难 主要就是对于那九个小格子知道是如何计算序号的 然后就是一个一个查找格子内的元素而已 因为集合的天然去重性 所以在创建开始的存储时 使用集合是个很不错的选择

    码字不易 喜欢请点赞收藏~

    你可能感兴趣的:(算法)