[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 rowfor i in range(9):hashset = set()for j in range(9):if board[i][j] in hashset and board[i][j] != '.':return Falsehashset.add(board[i][j])# check each colfor i in range(9):hashset = set()for j in range(9):if board[j][i] in hashset and board[j][i] != '.':return Falsehashset.add(board[j][i])# check 3x3for 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 Falsehashset.add(board[i][j])if board[i + 1][j] in hashset and board[i + 1][j] != '.':return Falsehashset.add(board[i + 1][j])if board[i + 2][j] in hashset and board[i + 2][j] != '.':return Falsehashset.add(board[i + 2][j])if board[i][j + 1] in hashset and board[i][j + 1] != '.':return Falsehashset.add(board[i][j + 1])if board[i + 1][j + 1] in hashset and board[i + 1][j + 1] != '.':return Falsehashset.add(board[i + 1][j + 1])if board[i + 2][j + 1] in hashset and board[i + 2][j + 1] != '.':return Falsehashset.add(board[i + 2][j + 1])if board[i][j + 2] in hashset and board[i][j+ 2] != '.':return Falsehashset.add(board[i][j])if board[i + 1][j + 2] in hashset and board[i + 1][j + 2] != '.':return Falsehashset.add(board[i + 1][j])if board[i + 2][j + 2] in hashset and board[i + 2][j + 2] != '.':return Falsehashset.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 Sudokureturn Truedef valid_cols(self, board: List[List[str]]) -> bool:# return if each col is a valid Sudokureturn Truedef valid_three_by_three(self,board: List[List[str]], i: int, j: int) -> bool:# return if each 3x3 is a valid Sodukufor r in range(i, i + 1, 3):for c in range(0, i + 1, 3):return Truedef valid_nine(self, board: List[List[str]]) -> bool:# return if the entire board can be divide into 9 valid 3x3for r in range(0, 9, 3):for c in range(0, 9, 3):if not valid_three_by_three(r, c):return Falsereturn Truedef 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 == ".":continueif (num in rows[r]or num in cols[c]or num in squares[(r // 3, c // 3)]):return Falsecols[c].add(num)rows[r].add(num)squares[(r // 3, c // 3)].add(num)return True