请你判断一个 9 x 9
的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
1-9
在每一行只能出现一次。1-9
在每一列只能出现一次。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)
这三个条件一旦有一个条件不满足 就直接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) 集合的天然语义与数独的不允许一行出现两个相同元素 相符合 代码可读性更强
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常用的四大数据结构:列表 字典 集合 元组
这个代码不算难 主要就是对于那九个小格子知道是如何计算序号的 然后就是一个一个查找格子内的元素而已 因为集合的天然去重性 所以在创建开始的存储时 使用集合是个很不错的选择
码字不易 喜欢请点赞收藏~