import java.util.Scanner;publicclassSudoku{privatestatic Scanner input;publicstaticvoidmain(String[] args){// Read a Sudoku puzzleint[][] grid =readAPuzzle();if(!isValid(grid))
System.out.println("Invalid input");elseif(search(grid)){
System.out.println("The solution is found:");printGrid(grid);}else
System.out.println("No solution");}/** Read a Sudoku puzzle from the keyboard */publicstaticint[][]readAPuzzle(){
input =newScanner(System.in);
System.out.println("Enter a Sudoku puzzle:");int[][] grid =newint[9][9];for(int i =0; i <9; i++)for(int j =0; j <9; j++)
grid[i][j]= input.nextInt();return grid;}/** Obtain a list of free cells from the puzzle */publicstaticint[][]getFreeCellList(int[][] grid){// Determine the number of free cells int numberOfFreeCells =0;for(int i =0; i <9; i++)for(int j =0; j <9; j++)if(grid[i][j]==0)
numberOfFreeCells++;// Store free cell positions into freeCellList int[][] freeCellList =newint[numberOfFreeCells][2];int count =0;for(int i =0; i <9; i++)for(int j =0; j <9; j++)if(grid[i][j]==0){
freeCellList[count][0]= i;
freeCellList[count][1]= j;
count++;}//将空出的位置对应的行和列存入数组return freeCellList;}/** Print the values in the grid */publicstaticvoidprintGrid(int[][] grid){for(int i =0; i <9; i++){for(int j =0; j <9; j++)
System.out.print(grid[i][j]+" ");
System.out.println();}}/** Search for a solution */publicstaticbooleansearch(int[][] grid){int[][] freeCellList =getFreeCellList(grid);// Free cellsif(freeCellList.length ==0)returntrue;// "No free cells");int k =0;// Start from the first free cell,定位器,确定当前空白位置的序号 while(true){int i = freeCellList[k][0];int j = freeCellList[k][1];//获取空白位置的行数与列数if(grid[i][j]==0)//确认空白位置处的数字是否为0
grid[i][j]=1;// Fill the free cell with number 1if(isValid(i, j, grid)){if(k +1== freeCellList.length){//判断空白位置是否填补完毕returntrue;// A solution is found}else{// Move to the next free cell
k++;}}elseif(grid[i][j]<9){// Fill the free cell with the next possible value
grid[i][j]= grid[i][j]+1;}else{// free cell grid[i][j] is 9, backtrack(回溯)本题关键while(grid[i][j]==9){if(k ==0){returnfalse;// No possible value}
grid[i][j]=0;// Reset to free cell
k--;// Backtrack to the preceding free cell
i = freeCellList[k][0];
j = freeCellList[k][1];}// Fill the free cell with the next possible value, // search continues from this free cell at k
grid[i][j]= grid[i][j]+1;}}}/** Check whether grid[i][j] is valid in the grid */publicstaticbooleanisValid(int i,int j,int[][] grid){// Check whether grid[i][j] is valid at the i's rowfor(int column =0; column <9; column++)if(column != j && grid[i][column]== grid[i][j])returnfalse;// Check whether grid[i][j] is valid at the j's columnfor(int row =0; row <9; row++)if(row != i && grid[row][j]== grid[i][j])returnfalse;// Check whether grid[i][j] is valid in the 3 by 3 box(小九宫格)for(int row =(i /3)*3; row <(i /3)*3+3; row++)for(int col =(j /3)*3; col <(j /3)*3+3; col++)if(row != i && col != j && grid[row][col]== grid[i][j])returnfalse;returntrue;// The current value at grid[i][j] is valid}/** Check whether the fixed cells are valid in the grid */publicstaticbooleanisValid(int[][] grid){for(int i =0; i <9; i++)for(int j =0; j <9; j++)if(grid[i][j]<0|| grid[i][j]>9||(grid[i][j]!=0&&!isValid(i, j, grid)))returnfalse;returntrue;// The fixed cells are valid}}