Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character '.'
.
You may assume that there will be only one unique solution.
A sudoku puzzle...
...and its solution numbers marked in red.
Solution: use the back tracking and brute force.
Note:
1) isValid()用来判断board[i][j]插入的字符是否合法;
2) char类型的变量可以直接比较大小并自增;
3) 填充数字时,采用int pos来记录位置,int i = pos/9, int j = pos%9, i,j 表示行列的位置。
4) 进行回溯的时候必须有返回值,以判定是否合法。
5) 代码48~50行一开始写成
if(isValid(board,i,j)){
solveS(board,pos+1);
}
没有使用isValid(board,i,j) && solveS(board,pos+1),导致了递归方法没有办法回溯,只能继续递归下去直到退出。
这样默认为上一级填充的字符均为正确的,会导致最终结果有空缺的'.' 。
public class Solution {
public boolean isValid(char[][] board, int x, int y){
Set<Character> rowCheck = new HashSet<Character>();
for(int i=0; i<9; i++){
if(rowCheck.contains(board[x][i])){
return false;
}
if(board[x][i]<='9' && board[x][i]>='1'){
rowCheck.add(board[x][i]);
}
}
Set<Character> colCheck = new HashSet<Character>();
for(int i=0; i<9; i++){
if(colCheck.contains(board[i][y])){
return false;
}
if(board[i][y]<='9' && board[i][y]>='1'){
colCheck.add(board[i][y]);
}
}
Set<Character> squCheck = new HashSet<Character>();
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
int m =x/3*3+i;
int n = y/3*3+j;
if(squCheck.contains(board[m][n])){
return false;
}
if(board[m][n]>='1' && board[m][n]<='9'){
squCheck.add(board[m][n]);
}
}
}
return true;
}
public boolean solveS(char[][] board, int pos){
if(pos > 9*9-1){
return true;
}
int i = pos/9;
int j = pos%9;
if(board[i][j] == '.'){
for(char k='1'; k<='9'; k++){
board[i][j] = k;
if(isValid(board,i,j) && solveS(board,pos+1)){
//must use '&&' and 'return' here, for back tracking
return true;
}
board[i][j] = '.';
}
}else{
return solveS(board, pos+1);
}
return false;
}
public void solveSudoku(char[][] board) {
// Start typing your Java solution below
// DO NOT write main() function
solveS(board, 0);
}
}