📅  最后修改于: 2023-12-03 15:40:36.517000             🧑  作者: Mango
数独板是一种有数字的矩阵,通常由 9 行,9 列组成。每行和每列都必须包含 1~9 这九个数字,同样,9 个宫(也就是 3*3 的矩阵)内也必须包含 1~9 这九个数字。本文介绍如何检查给定的数独板配置是否有效。
暴力求解是最容易想到的方法,它可以分别检查每一行、每一列、每一个宫内是否满足数独的合法性。
以下是 Python 代码示例:
def isValidSudoku(board: List[List[str]]) -> bool:
def is_valid(values: List[str]) -> bool:
values = [v for v in values if v != '.']
return len(values) == len(set(values))
for i in range(9):
# 检查第 i 行是否合法
if not is_valid(board[i]):
return False
# 检查第 i 列是否合法
if not is_valid([board[j][i] for j in range(9)]):
return False
# 检查第 (i//3, i%3) 个宫内是否合法
x, y = i // 3, i % 3
values = [
board[3*x+i][3*y+j]
for i in range(3) for j in range(3)
]
if not is_valid(values):
return False
return True
上面的代码中,is_valid
函数用来判断一个数组是否合法。该函数先将数组中的所有空位去掉,然后判断去掉空位后剩余的数字个数是否等于去重后的数字个数,如果是,则合法。
主函数中的代码实现如下:
如果任意一步检查发现不合法,就直接返回 False;如果所有检查都通过,则返回 True。
方法一的时间复杂度为 $O(1)$,因为只需要遍历一次整个数独板;空间复杂度为 $O(1)$,因为只需要几个计数器,不需要开辟额外的空间。
哈希表可以用来检查一个数独板是否合法。只需要遍历整个数独板,用一个哈希表记录每行、每列、每个宫内数字出现的次数即可。
以下是 Python 代码示例:
def isValidSudoku(board):
rows = [{} for i in range(9)]
cols = [{} for i in range(9)]
boxes = [{} for i in range(9)]
for i in range(9):
for j in range(9):
num = board[i][j]
if num != '.':
num = int(num)
box_index = (i // 3 ) * 3 + j // 3
rows[i][num] = rows[i].get(num, 0) + 1
cols[j][num] = cols[j].get(num, 0) + 1
boxes[box_index][num] = boxes[box_index].get(num, 0) + 1
if rows[i][num] > 1 or cols[j][num] > 1 or boxes[box_index][num] > 1:
return False
return True
上述代码中,分别用 rows
、cols
、boxes
来分别记录每一行、每一列、每个宫内出现的数字的次数,如果发现某个数字出现的次数超过 1,就说明该数独板不合法,可以直接返回 False。
方法二的时间复杂度为 $O(1)$,空间复杂度为 $O(1)$。不过要注意,方法二的执行速度比方法一要慢。