LeetCode第37题 Sudoku Solver
/*
Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:
1.Each of the digits 1-9 must occur exactly once in each row.
2.Each of the digits 1-9 must occur exactly once in each column.
3.Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.
Empty cells are indicated by the character '.'.
Note:
The given board contain only digits 1-9 and the character '.'.
You may assume that the given Sudoku puzzle will have a single unique solution.
The given board size is always 9x9.
*/
import java.util.*;
public class SudokuSolver{
public static void main(String[] args){
char Sudoku[][] = {
{'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'}};
SudokuSolver ss = new SudokuSolver();
boolean result = ss.solveSudoku(Sudoku);
System.out.println(result);
}
public boolean solveSudoku(char[][] board) {
/*
解题思想:
1.填入一个数到方格,检查填入的数是否有效,有效则执行2
2.当填入一个有效数后,再填入下一个有效数,执行1
3.当填入一个有效数后,下一个空找不到有效数,则回退,执行1
4.递归执行1、2、3
*/
return solver(board);
}
private boolean solver(char[][] board) {
for (int i=0;i<9;i++){
for(int j=0;j<9;j++){
// 准备填入数字
if(board[i][j] == '.'){
char num = '1';
// 每个空格尝试0-9,直到找到,或返回false
while(num <= '9'){
if (isValid(board,i,j,num)){
//填入的数字有效,递归方式填入下一个有效数
board[i][j] = num;
if(solver(board)){
// 递归的询问接下来是否能够填入有效数字,若都能返回true
// break只能跳出当前的循环,两层循环跳出是比较复杂的
return true;
}else{
// 不能一直递归的询问填入有效数字,回退,尝试下一个数
board[i][j] = '.';
}
}
num += 1;
}
// 当前方格不能填入有效数字
return false;
}
}
}
// 若数独无解,则在双循环的时候就会返回false
// 执行到当前位置,则表示最后一个空格不需要填数
return true;
}
// 判断输入的数在所在行、列、方框是否存在
private boolean isValid(char[][] board,int row,int col,char insert){
for (int i=0;i<9;i++){
if (board[row][i] == insert) return false;
}
for (int i=0;i<9;i++){
if (board[i][col] == insert) return false;
}
// 计算出方框的顶点空格坐标,而不是横向、竖向第几个方框
int rowNum = row/3 * 3;
int colNum = col/3 * 3;
for (int i=0;i<3;i++){
for(int j=0;j<3;j++){
if (board[rowNum+i][colNum+j]== insert) return false;
}
}
return true;
}
}