[python 刷题] 36 Valid Sudoku
题目:
Determine if a
9 x 9
Sudoku board is valid. Only the filled cells need to be validated according to the following rules:
Each row must contain the digits
1-9
without repetition.Each column must contain the digits
1-9
without repetition.Each of the nine
3 x 3
sub-boxes of the grid must contain the digits1-9
without repetition.Note:
A Sudoku board (partially filled) could be valid but is not necessarily solvable.
Only the filled cells need to be validated according to the mentioned rules.
这道题解数独,其实还是比较简单的,只是验证当前板子上有的数字能否构成一个合法的数独,而一个合法的数独就是每行、每列、每个 2 x 3
的盒子里都只能有不重复的 1-9
,按照这个逻辑硬写就行
因为空间大小就是 9 x 9
,所以不管怎么跑时间和空间复杂度都是
O
(
1
)
O(1)
O(1),非常丑陋的解法:
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
# a valid sodoku needs to have unique value on
# each row
# each col
# each 3x3
# check each row
for i in range(9):
hashset = set()
for j in range(9):
if board[i][j] in hashset and board[i][j] != '.':
return False
hashset.add(board[i][j])
# check each col
for i in range(9):
hashset = set()
for j in range(9):
if board[j][i] in hashset and board[j][i] != '.':
return False
hashset.add(board[j][i])
# check 3x3
for i in range(0, 9, 3):
for j in range(0, 9, 3):
hashset = set()
if board[i][j] in hashset and board[i][j] != '.':
return False
hashset.add(board[i][j])
if board[i + 1][j] in hashset and board[i + 1][j] != '.':
return False
hashset.add(board[i + 1][j])
if board[i + 2][j] in hashset and board[i + 2][j] != '.':
return False
hashset.add(board[i + 2][j])
if board[i][j + 1] in hashset and board[i][j + 1] != '.':
return False
hashset.add(board[i][j + 1])
if board[i + 1][j + 1] in hashset and board[i + 1][j + 1] != '.':
return False
hashset.add(board[i + 1][j + 1])
if board[i + 2][j + 1] in hashset and board[i + 2][j + 1] != '.':
return False
hashset.add(board[i + 2][j + 1])
if board[i][j + 2] in hashset and board[i][j+ 2] != '.':
return False
hashset.add(board[i][j])
if board[i + 1][j + 2] in hashset and board[i + 1][j + 2] != '.':
return False
hashset.add(board[i + 1][j])
if board[i + 2][j + 2] in hashset and board[i + 2][j + 2] != '.':
return False
hashset.add(board[i + 2][j + 2])
return True
其实就是硬解,反正能写完就行
这里提供另外两个稍微好一点的写法,一个是使用几个 helper function:
class Solution:
def valid_rows(self, board: List[List[str]]) -> bool:
# return if each row is a valid Sudoku
return True
def valid_cols(self, board: List[List[str]]) -> bool:
# return if each col is a valid Sudoku
return True
def valid_three_by_three(self,board: List[List[str]], i: int, j: int) -> bool:
# return if each 3x3 is a valid Soduku
for r in range(i, i + 1, 3):
for c in range(0, i + 1, 3):
return True
def valid_nine(self, board: List[List[str]]) -> bool:
# return if the entire board can be divide into 9 valid 3x3
for r in range(0, 9, 3):
for c in range(0, 9, 3):
if not valid_three_by_three(r, c):
return False
return True
def isValidSudoku(self, board: List[List[str]]) -> bool:
return self.valid_rows(board) and self.valid_cols(board) and self.valid_nine(board)
没有写完,因为最后的I写法更好一些
就是用 dict 的写法,这个写法应该是最简洁的了,用 row+col 的组合作为 key,只写一重遍历:
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
cols = collections.defaultdict(set)
rows = collections.defaultdict(set)
squares = collections.defaultdict(set) # key = (r /3, c /3)
for r in range(9):
for c in range(9):
num = board[r][c]
if num == ".":
continue
if (
num in rows[r]
or num in cols[c]
or num in squares[(r // 3, c // 3)]
):
return False
cols[c].add(num)
rows[r].add(num)
squares[(r // 3, c // 3)].add(num)
return True