Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:
1-9
must occur exactly once in each row.1-9
must occur exactly once in each column.1-9
must occur exactly once in each of the 9 3x3
sub-boxes of the grid.Empty cells are indicated by the character '.'
.
A sudoku puzzle...
Note:
1-9
and the character '.'
.9x9
.求解数独,hard级别。
数独的题目: leetcode 36. Valid Sudoku 求解是否符合规则。
这个题目还要复杂,在上个题目的valid基础上做了拓展。主要还是使用了回溯法:对于每个空着格子填入1到9,每填入一个数字都判定其是否合法,如果合法就继续下一次,或者失败回溯到上一个点时把数字设回 '.',。
判断新加入的数字是否合法时,只需要判定当前数字是否合法,不需要判定这个数组是否为数独数组,因为之前加进的数字都是合法的。校验合法的方法跟上一篇类似:分别校验行、列、及小3*3区域。
public static void main(String[] args) {
char[][] 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'}
};
solveSudoku(board);
System.out.println(JSON.toJSON(board));
}
public static void solveSudoku(char[][] board) {
helper(board);
}
private static boolean helper(char[][] board) {
//遍历整个数独的所有字符
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
//非空跳过
if (board[i][j] != '.') {
continue;
}
//尝试遍历要填充的数字
for(char k='1';k<='9';k++){
if (isValid(board, i, j, k)) {
board[i][j]=k;
//填充完毕之后继续调用该函数填充下一个点
if(helper(board)){
return true;
}
//如果solve(board)返回false,则说明前面的数字填充有误,将其还原,尝试下一个数字
board[i][j]='.';
}
}
//如果1-9都无法满足则说明之前的数字填错了,回溯到原始状态
return false;
}
}//所有的空格被填充完毕,返回true
return true;
}
private static boolean isValid(char[][] board, int i, int j, char k) {
for(int x=0;x<9;x++){
if(board[x][j]!='.' && board[x][j]== k){
return false;
}
if(board[i][x] !='.' && board[i][x]==k){
return false;
}
if(board[3*(i/3)+x/3 ][3*(j/3)+x%3] !='.' && board[3*(i/3)+x/3 ][3*(j/3)+x%3]==k){
return false;
}
}
return true;
}
Runtime: 6 ms, faster than 70.34% of Java online submissions for Sudoku Solver.
Memory Usage: 34.7 MB, less than 71.93% of Java online submissions forSudoku Solver.
后来看了网上的花花酱大神的,https://zxi.mytechroad.com/blog/searching/leetcode-37-sudoku-solver/
DFS+ 回溯。 使用3个二维数组来保存面板的行,列,九宫格信息,这样就省去了循环调用isValid函数进行判断的过程。3ms 快得飞起啊。