题目
Determine if a 9x9 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 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition.
A partially filled sudoku which is valid.
The Sudoku board could be partially filled, where empty cells are filled with the character '.'.
Example 1:
Input:
[
["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:
[
["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.
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.
- The given board contain only digits 1-9 and the character '.'.
- The given board size is always 9x9.
解题思路
玩过数独的人都应该清楚,本题就是要求对给出的9*9数组进行验证,如果满足:
1、横向数字只有1-9且不重复("."为补充占位,后续不再解释)
2、竖向数字只有1-9且不重复
3、把99的矩阵分成9个33的矩阵,每个矩阵中数字只有1-9且不重复
依照上面的解题思路,就是要对9*9的矩阵进行3次判断,全部校验通过则通过,反之不通过。
代码实现
以下为具体代码实现,仅供参考
public class Main {
public static void main(String[] args) {
Main main = new Main();
char[][] arr = main.init();
main.isValidSudoku(arr);
}
// 包含元素集合
private Character[] demo = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '.'};
public boolean isValidSudoku(char[][] board) {
if (checkHorizontal(board) && checkVertical(board) && checkGrid(board)) {
System.out.println(true);
return true;
} else {
System.out.println(false);
return false;
}
}
/**
* 初始化数组
*
* @return
*/
private char[][] init() {
char[][] arr = {
{'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'}
};
// char[][] arr = {{'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'}};
return arr;
}
/**
* 判断横向9个数字是否有重复
*
* @param arr
* @return
*/
private boolean checkHorizontal(char[][] arr) {
List<Character> strings = Arrays.asList(demo);
Set<Character> set = new HashSet<>();
for (char[] a : arr) {
set.clear();
for (char aa : a) {
if (aa == '.') {
continue;
} else if (strings.contains(aa) && !set.contains(aa)) {
set.add(aa);
} else {
return false;
}
}
}
return true;
}
/**
* 判断竖向9个数字是否有重复
*
* @param arr
* @return
*/
private boolean checkVertical(char[][] arr) {
char[][] tem = new char[9][9];
// 将原9*9矩阵翻转
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
tem[j][i] = arr[i][j];
}
}
return checkHorizontal(tem);
}
/**
* 判断3*3的9个数字是否有重复
*
* @param arr
* @return
*/
private boolean checkGrid(char[][] arr) {
char[][] tem = new char[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
// [i / 3 * 3 + j / 3]:确认当前元素属于3*3矩阵中第几块
// [j % 3 * 3 + i % 3]:确认当前元素在所属元素块中是第几个元素
tem[i / 3 * 3 + j / 3][j % 3 * 3 + i % 3] = arr[i][j];
}
}
return checkHorizontal(tem);
}
}