题目:Sudoku Solver
难度:hard
问题描述:
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.
解题思路:
这道题是上一题的进一步解答,也是我目前花费时间最长的一道题,一共做了大约6个小时,思路其实很快就有,也就是暴力的回溯法,但是在边界条件上一直出错,以及对迭代的使用还不是很熟练,对情况的分析讨论不细致导致的。
简单的思路就是将空着的格子依次填入1-9,填入后判断是否合格:1.行是否无重复 2.列是否无重复 3.3*3是否无重复。不满足则出栈,若是满足则进栈。
具体代码如下:
package leetCode_hard;
public class h_37_SudokuSolver {
static int[]temp=new int[9];
static char[]temp2=new char[9];
static char c;
public void solveSudoku(char[][] board) {
board=backtracking(board,0,0);
// System.out.println("最终结果:");
show(board);
}
public char[][] backtracking(char[][]board,int ii,int jj){
int i,j,k,x,a,b;
char c;
boolean flag=true,flag2=true; //初始化门
for(i=0;i<9;i++){
for(j=0;j<9;j++){
if(flag){ //初始化 使i、j跳转到正确值
i=ii;j=jj;
flag=false; //初始化结束
}
c=board[i][j]; //获取该点值
if(c!='.'){ //如果board[i][j]已经有定值了 则跳过 检查下一个点
if(jj==8&&ii==8){
return board;
}else{
continue;
}
}
for(k=0;k<9;k++){ //board[i][j]为空,以次填入1-9
board[i][j]=(char)(k-0+(int)'1'); //int转char
/**********检查行是否重复*************/
for(int z=0;z<9;z++){
temp2[z]=board[i][z];
}
if(!isnotchongfu(temp2)){ //行重复了
continue;
}
/**********检查列是否重复*************/
for(int z=0;z<9;z++){
temp2[z]=board[z][j];
}
if(!isnotchongfu(temp2)){ //列重复了
continue;
}
/**********检查3*3是否重复*************/
x=0;
for(int z=(i/3*3);z<(i/3*3)+3;z++){
for(int y=(j/3*3);y<(j/3*3)+3;y++){
temp2[x++]=board[z][y];
}
}
if(!isnotchongfu(temp2)){ //3*3重复了
continue;
}
// System.out.println("----没有重复");
/**********调用递归并检查是否达到边界*************/
if(j!=8){
board=backtracking(board,i,j+1).clone();
for(a=0;a<9;a++){ //检查是否全部填写完毕
for(b=0;b<9;b++){
if(board[a][b]=='.'){
flag2=false;
}
}
}
if(flag2==false){ //未填完
flag2=true;
continue;
}
return board;
}else{
if(i!=8){
board=backtracking(board,i+1,0).clone();
for(a=0;a<9;a++){
for(b=0;b<9;b++){
if(board[a][b]=='.'){
flag2=false;
}
}
}
if(flag2==false){
flag2=true;
continue;
}
return board;
}else{ //board[8][8] 数独搜索完成
return board;
}
}
}
board[i][j]='.'; //到这的1是重复后跳过来的2是k循环结束过来的 需返回去
return board;
}
}
return board;
}
public static void show(char[][] board){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(j!=0){
System.out.print(board[i][j]+" ");
}else{
System.out.println();
System.out.print(board[i][j]+" ");
}
}
}
System.out.println("");
}
public static boolean isnotchongfu(char[] nums){
for(int j=0;j<9;j++){
temp[j]=0;
}
for(int i=0;i<9;i++){
c=nums[i];
if(c!='.'){
if(temp[(int)(c-'1')]==0){
temp[(int)(c-'1')]++;
}else{
return false;
}
}
}
return true;
}
public static void main(String[]args){
char[][] board=new char[9][];
char[][] board11=new char[9][];
char[] board1={'.','2','.','.','.','6','7','8','9'};
char[] board2={'4','5','6','7','8','9','1','2','3'};
char[] board3={'7','8','9','1','2','3','4','5','6'};
char[] board4={'2','1','4','3','6','5','8','9','7'};
char[] board5={'3','6','5','8','9','7','2','1','4'};
char[] board6={'8','9','7','2','1','4','.','.','.'};
char[] board7={'.','.','.','6','4','2','.','.','.'};
char[] board8={'.','.','.','9','7','8','5','3','1'};
char[] board9={'.','.','.','5','3','1','6','4','2'};
/*
char[] board1={'1','2','3','4','5','6','7','8','9'};
char[] board2={'4','5','6','7','8','9','1','2','3'};
char[] board3={'7','8','9','1','2','3','4','5','6'};
char[] board4={'2','1','4','3','6','5','8','9','7'};
char[] board5={'3','6','5','8','9','7','2','1','4'};
char[] board6={'8','9','7','2','1','4','3','6','5'};
char[] board7={'5','3','1','6','4','2','9','7','8'};
char[] board8={'6','4','2','9','7','8','5','3','1'};
char[] board9={'9','7','8','5','3','1','6','4','2'};
*/
char[] temp1={'.','.','9','7','4','8','.','.','.'};
char[] temp2={'7','.','.','.','.','.','.','.','.'};
char[] temp3={'.','2','.','1','.','9','.','.','.'};
char[] temp4={'.','.','7','.','.','.','2','4','.'};
char[] temp5={'.','6','4','.','1','.','5','9','.'};
char[] temp6={'.','9','8','.','.','.','3','.','.'};
char[] temp7={'.','.','.','8','.','3','.','2','.'};
char[] temp8={'.','.','.','.','.','.','.','.','6'};
char[] temp9={'.','.','.','2','7','5','9','.','.'};
board[0]=temp1;board[1]=temp2;board[2]=temp3;
board[3]=temp4;board[4]=temp5;board[5]=temp6;
board[6]=temp7;board[7]=temp8;board[8]=temp9;
board11[0]=board1;board11[1]=board2;board11[2]=board3;
board11[3]=board4;board11[4]=board5;board11[5]=board6;
board11[6]=board7;board11[7]=board8;board11[8]=board9;
h_37_SudokuSolver s=new h_37_SudokuSolver();
s.solveSudoku(board);
}
}