tags:
- 暴力解法
categories:
- 算法题解
算法题解第六题:判断给出的数独是否有效
题目
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
示例 1:
输入:
[
[“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”]
]
输出: true
示例 2:
输入:
[
[“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”]
]
输出: false
解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。
但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-sudoku
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
###解法1:暴力解法
题目要求只需要对给出的数据进行判断是否有效,并不需要判断是否有解。因此一种暴力解法就是对给出三个条件:
1.每行没有重复数字
2.每列没有重复数字
3.每个3*3的小区域没有重复数字
进行实现既可,当输入同时满足以上三个条件时才返回True,否则返回False
def isValidSudoku(self, board: List[List[str]]) -> bool:
def judgeRow(board: List[List[str]]): #判断行函数
for i in range(9): #设置一个空集合,查看每行元素是否有重复,遍历完一行后清空
s = set()
for j in range(9):
if board[i][j] == ".":
continue
if board[i][j] in s:
return False
else:
s.add(board[i][j])
s.clear()
return True
def judgeCol(board:List[List[str]]): #判断列函数
for i in range(9): #设置一个空集合,查看每行元素是否有重复,遍历完一行后清空
s = set()
for j in range(9):
if board[j][i] == ".":
continue
if board[j][i] in s:
return False
else:
s.add(board[j][i])
s.clear()
return True
def judgeBlock(board:List[List[str]]): #判断小区域函数:
for i in range(3): #i,j表示外部坐标,即位于哪个区块
for j in range(3):
s = set()
for k in range(9):
x = k//3 #x,y表示区块内的坐标
y = k%3 #合并得到[3*i+x][3*j+y]就是当前坐标
if board[3*i+x][3*j+y] == ".":
continue
if board[3*i+x][3*j+y] in s:
return False
else:
s.add(board[3*i+x][3*j+y])
s.clear()
return True
if ( judgeCol(board) and judgeRow(board) and judgeBlock(board)): #三个条件联立判断
return True
return False
解法2:位运算
上面方法效率不高,所以在看题解时看到一位大佬写的位运算方法解题,大开眼界。不过大佬写的是java版,这里写一个自己理解的python
版尝试实现。
原作者:parsee
链接:https://leetcode-cn.com/problems/valid-sudoku/solution/javabian-ma-yong-intbiao-shi-ji-he-yong-wei-yun-su/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。