算法之6-回溯法解数独问题

 刚开始学习的时候,总是不知道对数组进行回溯的时候,怎么保证找到的是下一个空值, 所以写好一半的代码就放在一边,一个星期之后回过头再看回溯法解数独的时候,突然醒悟过来:

原来在构造数组的时候,以0值代替空值,当从1-9的某一个数填入该处的时候,该处就不是0值,回溯重新调用方法的时候,找到的0值就是下一处的0值了.
注意点:  
 (1).sudoku方法的返回值是布尔值,这样子"&&"两边才都是布尔值
 (2)九宫格的获得iGrid和jGrid都是用i,j对3整除再乘以3(以前错误认识:九宫格是以i,j为中心的九宫)
 (3)数独的表示,空值用0表示
今天还有其它事,把待解决的记录下来,以便以后参考:
  待解决问题:
   (1)输出多个相同的数独解
代码如下:
public class Sudodu {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][] chess = { 
				{0,4,2,0,6,3,0,0,9},
				{6,0,0,0,1,0,0,0,5},
				{3,0,0,0,2,0,4,8,0},
				{1,0,0,5,0,2,6,0,8},
				{4,0,0,0,0,7,0,0,1},
				{9,0,5,6,0,0,0,0,7},
				{0,3,6,0,5,0,0,0,2},
				{2,0,0,0,7,0,0,0,4},
				{7,0,0,2,9,0,8,5,0}
				} ;
		sudoku(chess);
}

static boolean sudoku(int[][] chess) {
		// TODO Auto-generated method stub
		for(int i=0;i<9;i++)
		{
			for(int j=0;j<9;j++)
			{
				       //过滤掉不为0的情况
				   if(chess[i][j] != 0)
				  	continue;
						for(int d=1;d<=9;d++)
						{
							chess[i][j]=d;
							if(isValid(chess,i,j) && sudoku(chess) )
							{
								shuchushudu(chess);
								return true;
							}
							chess[i][j]=0;
						}
						return false;
			}
		}
		return true;
	}

	private static void shuchushudu(int[][] chess) {
	// TODO Auto-generated method stub
		for(int i=0;i<9;i++){
			for(int j=0;j<9;j++)
			{
			System.out.print(chess[i][j]+"  ");
			}
			System.out.println(" ");
		}
	System.out.println("--------------");
}

	private static boolean isValid(int[][] chess, int i, int j) {
		// TODO Auto-generated method stub
		boolean flag=true;
		int data=chess[i][j];
		for(int k=0;k<9;k++)
		{
			//i行相等
			if( (k!=j) && (chess[i][k]==data))
			{
			  return false;
			}
			//j列相等
			if( (k!=i) && (chess[k][j]==data))
			{
				return false;
			}
		}
		//九宫相等
		int iGrid=(i/3)*3;
		int jGrid=(j/3)*3;
		for(int k2=iGrid;k2<iGrid+3;k2++)
		{
			for(int k3=jGrid;k3<jGrid+3;k3++)
			{
				if((i==k2) && (j==k3))
				{
					continue;
				}
				if(chess[k2][k3]==data)
				{
					return false;
				}
			}
		}
		return true;
	}
}


结果输出:



5  4  2  8  6  3  7  1  9   
6  8  7  4  1  9  2  3  5   
3  9  1  7  2  5  4  8  6   
1  7  3  5  4  2  6  9  8   
4  6  8  9  3  7  5  2  1   
9  2  5  6  8  1  3  4  7   
8  3  6  1  5  4  9  7  2   
2  5  9  3  7  8  1  6  4   
7  1  4  2  9  6  8  5  3   


猜你喜欢

转载自blog.csdn.net/zhangchun888/article/details/50365676