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); } }