题目
判断一个 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 存在, 因此这个数独是无效的。
【说明】
- 一个有效的数独(部分已被填充)不一定是可解的。
- 只需要根据以上规则,验证已经填入的数字是否有效即可。
- 给定数独序列只包含数字 1-9 和字符 ‘.’ 。
- 给定数独永远是 9x9 形式的。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-sudoku
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路一
最直接的思路是三次循环,分别看每一行、每一列、每一个3*3小格是否满足条件。代码如下:
public boolean isValidSudoku(char[][] board){
List<Character> list = new ArrayList<>();
// 校验行
for(int i = 0; i < 9; i++){
char[] row = board[i];
for(char ch : row){
if(ch != '.'){
if(list.contains(ch)){
return false;
}else{
list.add(ch);
}
}
}
list.clear();
}
// 校验列
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
char ch = board[j][i];
if(ch == '.'){
continue;
}
if(list.contains(ch)){
return false;
}else{
list.add(ch);
}
}
list.clear();
}
// 校验3*3小格
for(int i = 0; i < 9; i++){
int row = i / 3;
int col = i % 3;
for(int j = row * 3; j < (row + 1) * 3; j++){
for(int k = col * 3; k < (col + 1) * 3; k++){
char ch = board[j][k];
if(ch == '.'){
continue;
}
if(list.contains(ch)){
return false;
}else{
list.add(ch);
}
}
}
list.clear();
}
return true;
}
思路二
其实一次循环就可以完成上述步骤。同时,可以利用数组来替代集合。代码如下:
public boolean isValidSudoku(char[][] board){
int[][] row = new int[9][9];
int[][] col = new int[9][9];
int[][] box = new int[9][9];
for(int r = 0; r < 9; r++){
for(int c = 0; c < 9; c++){
char data = board[r][c];
if(data == '.'){
continue;
}
int num = data - '1';
// 计算3*3小格的序号
int box_index = (r / 3) * 3 + c / 3;
if(row[r][num] != 0 || col[c][num] != 0 || box[box_index][num] != 0){
return false;
}
row[r][num] = 1;
col[c][num] = 1;
box[box_index][num] = 1;
}
}
return true;
}