[LeetCode] 36. Valid Sudoku_Medium tag: Array
2021-06-09 09:40 Johnson_强生仔仔 阅读(40) 评论(0) 编辑 收藏 举报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.
Example 1:
Input: 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"]] Output: true
Example 2:
Input: 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"]] Output: false Explanation: Same as Example 1, except with the 5 in the top left corner being modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.
Constraints:
board.length == 9
board[i].length == 9
board[i][j]
is a digit or'.'
.
Idea:用两个for loop 去检测每一个点,然后看该行,该列和所在的3 *3的小正方形中是否有相同的数,如果有表明invalid,最后两个for loop结束,返回True。
1. brute force
T: O(n * n * n) n = 9
S: O(1)
class Solution: def isValidSudoku(self, board: List[List[str]]) -> bool: for i in range(9): for j in range(9): if board[i][j] == '.': continue if not self.isValid(board, i, j): return False return True def isValid(self, board, i, j): c = board[i][j] for k in range(9): row = (i //3) * 3 + k //3 col = (j //3) * 3 + k % 3 if (k != j and c == board[i][k]) or (k != i and c == board[k][j]) or row != i and col != j and c == board[row][col]: return False return True
我们利用3个9 * 9的array去记录,
rowFlag[row][num] 的左下标row表示的是行数,右下标num表示的是(“实际数字” - 1),数值rowFlag[row][num]如果为False表示目前该row行没有出现过num + 1 这个数字,如果为True表明出现过num + 1这个数字。
同理,colFlag[col][num] 的左下标col表示的是列数,右下标num表示的是(“实际数字” - 1),数值colFlag[col][num]如果为False表示目前该col列没有出现过num + 1 这个数字,如果为True表明出现过num + 1这个数字。
最后,cellFlag[cellIndex][num]的左下标cellIndex表示的是哪个小正方形的index, 如下图所示,图是来自Leetcode这道题的solution,右下标num表示的是(“实际数字” - 1),数值cellFlag[cellIndex][num]如果为False表示目前该cellIndex的小正方形没有出现过num + 1 这个数字,如果为True表明出现过num + 1这个数字。
cellIndex = (row //3) * 3 + col //3 , 可以记住,或者自己推一下就可以了,可以带入row 和col进去试试看就明白了。
n = 9 in this case
T: O(n * n)
S: O(n * n)
Code
class Solution: def isValidSudoku(self, board: List[list[str]]) -> bool: rowFlag = [[False] * 9 for _ in range(9)] colFlag = [[False] * 9 for _ in range(9)] cellFlag = [[False] * 9 for _ in range(9)] for i in range(9): for j in range(9): if board[i][j] == '.': continue num = int(board[i][j]) - 1 cellIndex = (i//3) * 3 + j //3 if rowFlag[i][num] or colFlag[j][num] or cellFlag[cellIndex][num]: return False rowFlag[i][num] = True colFlag[j][num] = True cellFlag[cellIndex][num] = True return True