topic
https://leetcode-cn.com/problems/valid-sudoku/
Determine whether a 9x9 Sudoku is valid. You only need to verify whether the number you have entered is valid according to the following rules.
The numbers 1-9 can only appear once per line.
The numbers 1-9 can only appear once in each column.
The numbers 1-9 can only appear once in each 3x3 house separated by a thick solid line.
The picture above is a partially filled effective Sudoku.
The space in the Sudoku part has been filled with numbers, and the blank space is indicated by '.'.
Example 1:
Enter:
[
["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"]
]
Output: true
Example 2:
Enter:
[
["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"]
]
Output: false
Explanation: Except that the first number in the first line is changed from 5 to 8, the other numbers in the space are the same as in Example 1.
But because there are two 8s in the 3x3 palace in the upper left corner, this Sudoku is invalid.
Explanation:
A valid Sudoku (partially filled) is not necessarily solvable.
You only need to verify whether the number you have filled in is valid according to the above rules.
The given Sudoku sequence contains only the numbers 1-9 and the character '.'.
A given Sudoku is always in the form of 9x9.
Problem-solving ideas
-
The idea of naive is to verify separately by row, column, and nine grids, so that the number of loops is 3 9 * 9.
-
See the code below
naive version
. -
After observation, it is found that the numbers that have appeared in rows, columns, and nine-grid grids can actually be stored through collections, so that only a 9 * 9 cycle is needed.
-
See the code below
optimized version
. -
In addition, there are other optimization methods, such as not using set (), using an array instead, or even using bits for storage.
Code
# - naive version
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
# - check for each row
for row in range(9):
exist_set = set()
for col in range(9):
c = board[row][col]
if c == '.': continue
if c in exist_set:
return False
else:
exist_set.add(c)
# - check for each col
for col in range(9):
exist_set = set()
for row in range(9):
c = board[row][col]
if c == '.': continue
if c in exist_set:
return False
else:
exist_set.add(c)
# - check for each grid
for gr in range(3):
for gc in range(3):
exist_set = set()
for j in range(3):
for i in range(3):
c = board[gr*3 + j][gc*3 + i]
if c == '.': continue
if c in exist_set:
return False
else:
exist_set.add(c)
return True
# - optimized version
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
row_state_list = [set() for _ in range(9)]
col_state_list = [set() for _ in range(9)]
grid_state_list = [set() for _ in range(9)]
# - check for each cell
for row in range(9):
for col in range(9):
c = board[row][col]
if c == '.': continue
grid_index = (row//3)*3 + col//3
if c in row_state_list[row]: return False
if c in col_state_list[col]: return False
if c in grid_state_list[grid_index]: return False
row_state_list[row].add(c)
col_state_list[col].add(c)
grid_state_list[grid_index].add(c)
return True