leetCode练习(37)

题目: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);
		
	}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值