演算法之6-回溯法解數獨問題
阿新 • • 發佈:2019-01-21
剛開始學習的時候,總是不知道對陣列進行回溯的時候,怎麼保證找到的是下一個空值, 所以寫好一半的程式碼就放在一邊,一個星期之後回過頭再看回溯法解數獨的時候,突然醒悟過來:
原來在構造陣列的時候,以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