1. 程式人生 > >Leetcode #37. Sudoku Solver 數獨求解 結題報告

Leetcode #37. Sudoku Solver 數獨求解 結題報告

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); } }