給定一個 9x9 的數獨棋盤,請驗證這個棋盤是否有效。
數獨棋盤需滿足以下條件:
1-9
,不能重複。1-9
,不能重複。1-9
,不能重複。注意:
'.'
表示。範例 1
輸入:
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"]]
輸出:true
範例 2
輸入:
board =
[["8","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"]]
輸出:false
解釋:第一列有兩個 8,因此這個棋盤是無效的。
我們可以將數獨棋盤視為三部分來驗證:
對於每部分,我們可以使用 集合 來檢查是否有重複數字:
'.'
,則忽略。class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
rows = [set() for _ in range(9)]
cols = [set() for _ in range(9)]
boxes = [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]:
return False
rows[i].add(num)
# 檢查列
if num in cols[j]:
return False
cols[j].add(num)
# 檢查子方格
box_index = (i // 3) * 3 + (j // 3)
if num in boxes[box_index]:
return False
boxes[box_index].add(num)
return True
我們可以用 唯一標識符 來壓縮存儲需求,僅用一個集合來記錄每個數字是否出現過。
5
出現在第 0 行,標識為 "5 in row 0"
。5
出現在第 1 列,標識為 "5 in col 1"
。5
出現在子方格 (0,0),標識為 "5 in box 0-0"
。False
。class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
seen = set()
for i in range(9):
for j in range(9):
num = board[i][j]
if num == '.':
continue
row_key = f"{num} in row {i}"
col_key = f"{num} in col {j}"
box_key = f"{num} in box {i//3}-{j//3}"
if row_key in seen or col_key in seen or box_key in seen:
return False
seen.add(row_key)
seen.add(col_key)
seen.add(box_key)
return True
這種方法較為直觀,分開處理每部分。
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
def isValidSet(values):
nums = [v for v in values if v != '.']
return len(nums) == len(set(nums))
# 檢查行
for row in board:
if not isValidSet(row):
return False
# 檢查列
for col in zip(*board):
if not isValidSet(col):
return False
# 檢查子方格
for i in range(0, 9, 3):
for j in range(0, 9, 3):
box = [board[x][y] for x in range(i, i + 3) for y in range(j, j + 3)]
if not isValidSet(box):
return False
return True