描述
请你判断一个 9 x 9
的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
- 数字
1-9
在每一行只能出现一次。 - 数字
1-9
在每一列只能出现一次。 - 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。(请参考示例图)
注意:
- 一个有效的数独(部分已被填充)不一定是可解的。
- 只需要根据以上规则,验证已经填入的数字是否有效即可。
- 空白格用
'.'
表示。
提示:
board.length == 9
board[i].length == 9
board[i][j]
是一位数字(1-9
)或者'.'
示例
示例 1:
输入: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"]] 输出:true
示例 2:
输入: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"]] 输出:false 解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。
算法思路1
我们遍历每一行、每一列和每个 3x3 的宫格。对于每一行和每一列,我们使用 HashSet
来存储已经出现的数字,以检查是否有重复的数字。对于每个 3x3 的宫格,我们计算其索引,并使用相同的方法来检查其中的数字。
如果有任何一行、一列或一个 3x3 的宫格中存在重复的数字,就会返回 false
,表示数独无效。如果所有行、列和宫格中的数字都是有效的,则返回 true
,表示数独有效。
答案1
class Solution {
public boolean isValidSudoku(char[][] board) {
for(int i=0;i<9;i++){
HashSet<Character> row = new HashSet<>();
HashSet<Character> col = new HashSet<>();
HashSet<Character> box = new HashSet<>();
for(int j=0;j<9;j++){
if(board[i][j]!='.'&&!row.add(board[i][j])){
return false;
}
if(board[j][i]!='.'&&!col.add(board[j][i])){
return false;
}
int a =3*(i/3);
int b=3*(i%3);
if(board[a+j/3][b+j%3]!='.'&&!box.add(board[a+j/3][b+j%3])){
return false;
}
}
}
return true;
}
}
详解1
注意理解九宫格下标的计算。
int rowIndex = 3 * (i / 3);
:
- 这行代码计算了当前 3x3 宫格的起始行索引。
(i / 3)
表示当前行索引除以 3,得到的结果是当前 3x3 宫格在第几行。- 乘以 3 是为了将行索引映射到数独中的实际行索引(0、3、6)。
int colIndex = 3 * (i % 3);
:
- 这行代码计算了当前 3x3 宫格的起始列索引。
(i % 3)
表示当前列索引除以 3 的余数,得到的结果是当前 3x3 宫格在第几列。- 乘以 3 是为了将列索引映射到数独中的实际列索引(0、3、6)。
board[rowIndex + j / 3][colIndex + j % 3]
:
- 这行代码用于访问当前 3x3 宫格中的元素。
rowIndex + j / 3
表示当前行索引加上在当前 3x3 宫格中的相对行索引(0、1、2)。colIndex + j % 3
表示当前列索引加上在当前 3x3 宫格中的相对列索引(0、1、2)。- 通过这样的方式,我们可以在每个 3x3 宫格内遍历到所有的元素。
有关HashSet的用法详见:Java“集合与列表”知识速成笔记学完就去实战(三)-CSDN博客