1、题目
请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可;
数字 1-9 在每一行只能出现一次;
数字 1-9 在每一列只能出现一次;
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
注意:
一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
空白格用 ‘.’ 表示。
2、代码
from typing import List
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
# 整体思路:拿到所有需要比对的元素,然后进行重复判断。
# (1)求解每一行所有的非点元素放入列表,求解每一列的非点元素放入列表,求解每一区域的非点元素放入列表
# (2)然后判断所有数组是否存在重复元素,最终返回True和False
row = []
for y in board:
row.append([x for x in y if x != '.'])
col = []
for y in zip(*board):
col.append([x for x in y if x != '.'])
pal = []
for i in (0, 3, 6):
for j in (0, 3, 6):
pal.append([board[i + m][j + n] for m in range(3) for n in range(3) if board[i + m][j + n] != '.'])
print(row)
print(col)
print(pal)
return all(len(set(x)) == len(x) for x in (*row, *col, *pal))
# 哈希表真好啊,效率真高
row, col, sqrt = defaultdict(set), defaultdict(set), defaultdict(set)
for i in range(9):
for j in range(9):
val = board[i][j]
if val == '.':
continue
point = i // 3 * 3 + j // 3
if val in row[i] or val in col[j] or val in sqrt[point]:
print(i, j, val)
print(row, col, sqrt)
return False
row[i].add(val)
col[j].add(val)
sqrt[point].add(val)
return True
if __name__ == '__main__':
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"]
]
a = Solution()
print(a.isValidSudoku(board))
3、思路
1、整体思路:拿到所有需要比对的元素,然后进行重复判断
(1)求解每一行所有的非点元素放入列表,求解每一列的非点元素放入列表,求解每一区域的非点元素放入列表;
(2)然后判断所有数组是否存在重复元素,最终返回True和False;
2、这道题其实是让我们判断行、列、九宫格内是否存在重复的元素,如果存在返回False,否则True,分别维护行、列、九宫格三个哈希表,然后每次判断是否存在即可。如何判断当前的单元格,在哪个九宫格中,简单推倒下就能得出:x // 3 * 3 + y // 3