解题关键
关键是:怎样判断某个格子的数字在哪个block块儿,数独总共有9个block块儿
图片引用:
https://leetcode-cn.com/problems/valid-sudoku/solution/gong-shui-san-xie-yi-ti-san-jie-ha-xi-bi-ssxp/
具体实现上,判断是否出现过可以用哈希表、数组、位运算
Solution 1: 哈希表
代码1:遍历三次
第1次遍历:遍历行
第2次遍历:遍历列
第3次遍历:遍历block
这样遍历三次,能不能一次遍历解决行、列、block的判断呢?
class Solution(object):
def isValidSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: bool
"""
# for row
for i in range(0,9):
row = board[i]
hash_row = dict()
for j in range(0,9):
if row[j]!= '.':
if row[j] in hash_row.keys(): # 判断字典是否存在关键字的语句
return False
else:
hash_row[row[j]] = j
# for columns
board_trans = [[row[i] for row in board] for i in range(len(board[0]))]
for i in range(0,9):
column = board_trans[i]
hash_column = dict()
for j in range(0,9):
if column[j]!='.':
if column[j] in hash_column.keys():
return False
else:
hash_column[column[j]] = j
# for block
hash_block = dict()
for i in range(0,9):
hash_block[i] = dict()
for i in range(0,9):
for j in range(0,9):
if board[i][j] != '.':
idx_block = int(i/3)*3 + int(j/3)
if board[i][j] in hash_block[idx_block].keys():
return False
else:
hash_block[idx_block][board[i][j]] = board[i][j] # 具体数值不重要,有数做标记
return True
测试通过,运行成功
代码2:遍历一次
一次遍历过程中,分别去判断行是否满足要求、列是否满足要求、block是否满足要求,那么空间换时间的思想,建立哈希表数组
特别需要注意是,需要判断格子元素是’.‘的情况,如果格子元素是’.',那么什么都不做
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
col = [{} for i in range(0, 9)]
row = [{} for i in range(0, 9)]
block = [{} for i in range(0, 9)]
for i in range(0, 9):
for j in range(0, 9):
if board[i][j] != '.':
if board[i][j] in row[i]:
return False
else:
row[i][board[i][j]] = 1
if board[i][j] in col[j]:
print('col')
return False
else:
col[j][board[i][j]] = 1
idx_block = 3 * (i//3) + (j//3)
if board[i][j] in block[idx_block]:
print('block')
return False
else:
block[idx_block][board[i][j]] = 1
return True
Solution 2: 数组
用数组替代哈希表,因为哈希表的key值是[1,9],是数组的索引
虽然时间复杂度一样,但哈希表的更新和查询复杂度为均摊 O(1),而定长数组的的更新和查询复杂度则是严格 O(1)。(引用自参考链接:https://leetcode.cn/problems/valid-sudoku/solutions/1002073/gong-shui-san-xie-yi-ti-san-jie-ha-xi-bi-ssxp/)
但是从真实的时间来看,实际执行时间并没有比哈希表时间快,(ಥ﹏ಥ)
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
# Solution 2: 数组作为哈希表
col = [[0]*9 for i in range(0,9)]
row = [[0]*9 for i in range(0,9)]
block = [[0]*9 for i in range(0,9)]
for i in range(0, 9):
for j in range(0, 9):
if board[i][j] != '.':
if row[i][int(board[i][j])-1] == 0:
row[i][int(board[i][j])-1] = 1
else:
return False
if col[j][int(board[i][j])-1] == 0:
col[j][int(board[i][j])-1] = 1
else:
return False
idx_block = 3 * (i//3) + (j//3)
if block[idx_block][int(board[i][j])-1] == 0:
block[idx_block][int(board[i][j])-1] = 1
else:
return False
return True
Solution 3: 位运算
过于复杂,没有看懂,感兴趣的小伙伴可以参考下面链接中的大神讲解
https://leetcode.cn/problems/valid-sudoku/solutions/1002073/gong-shui-san-xie-yi-ti-san-jie-ha-xi-bi-ssxp/