Leetcode #37. Sudoku Solver 數獨求解 結題報告
阿新 • • 發佈:2019-01-27
1 解題報告
做法就只能是暴力的回溯了。。
- 方法是回溯,用各個標誌位來標誌是否存在衝突
- 如果數字原來就有了,那麼就跳過處理
- 因為答案只有一個,所以一旦找到,就要立馬跳出遞迴(如果你用的是棧實現的回溯可能會好處理些)
- 總之就是仔細些。。。我一次寫過的,而且耗時貌似還很短。。。
-
- 我沒用題目提示的雜湊,我用了陣列去判斷,因為這樣快!!!,還有char陣列還是先變成int陣列吧,不然算起來很累。。
2 原題
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.
3 AC解
/**
* 方法是回溯,用各個標誌位來標誌是否存在衝突
* 如果數字原來就有了,那麼就跳過處理
* 因為答案只有一個,所以一旦找到,就要立馬跳出遞迴(如果你用的是棧實現的回溯可能會好處理些)
* 總之就是仔細些。。。我一次寫過的,而且耗時貌似還很短。。。
*
* 我沒用題目提示的雜湊,我用了陣列去判斷,因為這樣快!!!,還有char陣列還是先變成int陣列吧,不然算起來很累。。
*
* */
public class Solution {
//各行各列的標誌位
boolean col[][]; //列
boolean row[][]; //行
boolean zone[][]; //九宮格內
char result[][];
//轉換成正數
int[][] tmp;
boolean flag;
public void find(int index){
if(index==81){
flag=true;
for(int i=0;i<9;i++){
for(int j=0;j<9 ;j++){
result[i][j]=(char)('0'+tmp[i][j]);
}
}
}
if(flag)
return;
int i=index/9,j=index%9;
if(tmp[i][j]==0){ // 此時等於0代表原來的是. 還沒有數字進行填充,才進行運算,否則直接到下一個了
for(int k=1;k<=9;k++){
if(col[j][k]==false && row[i][k]==false && zone[(i/3)*3+j/3][k]==false){
/**
* 遞迴的時候注意狀態的改變,進入遞迴前先改變狀態,跳出時要修正狀態回來*/
col[j][k]=true;
row[i][k]=true;
zone[(i/3)*3+j/3][k]=true;
tmp[i][j]=k;
find(index+1);
tmp[i][j]=0;
col[j][k]=false;
row[i][k]=false;
zone[(i/3)*3+j/3][k]=false;
}
}
}
else{
find(index+1);
}
}
public void solveSudoku(char[][] board) {
int i,j;
result=board;
flag=false;
col=new boolean[9][10];
row=new boolean[9][10];
zone=new boolean[9][10];
tmp=new int[9][9];
//第一遍的掃描設定初始位置和標誌位
for(i=0;i<9;i++){
for(j=0;j<9;j++){
if(board[i][j]!='.'){
tmp[i][j]=board[i][j]-'0';
col[j][tmp[i][j]]=true;
row[i][tmp[i][j]]=true;
zone[(i/3)*3+j/3][tmp[i][j]]=true;
}
}
}
find(0);
}
}