leetcode37 解數獨問題 hard
編寫一個程式,通過填充空格來解決數獨問題。
一個數獨的解法需遵循如下規則:
數字 1-9 在每一行只能出現一次。
數字 1-9 在每一列只能出現一次。
數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。
空白格用 ‘.’ 表示。
提示:
給定的數獨序列只包含數字 1-9 和字元 ‘.’ 。
你可以假設給定的數獨只有唯一解。
給定數獨永遠是 9x9 形式的。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/sudoku-solver
作為一個剛剛起步演算法的小弱雞,稍微記錄一下自己對於這題的設計思路吧,沒有嘗試高大上的辦法,我只用了最簡單的回溯辦法,但是這道題確實加深了我對於回溯的理解。
基本思路是對於一個數獨矩陣,設計一個函式helper(board,row,col),對於board[row][col]按進行1-9窮舉,並判斷isvalid,如果這一位填的數字滿足數獨矩陣條件,那麼就判斷helper(board,row,col+1),這裡需要思考的是我們希望這個遞迴函式的意義是什麼,我的回答是,我希望輸入board,row,col能夠判斷這之後的整個數獨能不能填完,以此為基點思考下去就會遇到一個問題:
最開始我設計的輔助函式是一個無返回的void函式,但是我發現這樣子無法知道後一位helper(board,row,col+1)是否能夠填完,所以將函式改為bool函式,那麼helper(board,row,col)的返回值判斷思路如下:
如果board[row][col]填了數字或者能填數字,那麼就判斷helper(board,row,col+1)是否是true,如果是那麼返回true;不是那就說明這一位填的數字不對,那就換一個數字,如果窮舉完9個數字都沒有返回true,那就說明helper(board,row,col)無法完成數獨,所以return false。
回溯的思想則體現在中間每次將choose的數字改回’.'的過程。
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
helper(board,0,0);
}
//輸入位置返回是否能填成功
bool helper(vector<vector<char>>& board,int row,int col){
if(row==8&&col==9){
//base case
return true;
}
//位置變化
if(col==9){
col=0;
row++;
}
//如果已經有數字了
if(board[row][col]!='.') return helper(board,row,col+1);
//沒數字的話窮舉此位置1-9
else{
for(int i=1;i<10;i++){
//choose
board[row][col]=(char)(i+'0');
bool flag=isvalid(row,col,board);
if(flag) {
if(helper(board,row,col+1)) return true;
}
//unchoose
board[row][col]='.';
}
//如果9個數都舉完,仍然不能返回true,說明是之前選的數字出錯了,因此返回false
return false;
}
}
bool isvalid(int row,int col,vector<vector<char>>& board){
int num=board[row][col];
for(int i=0;i<9;i++){
if(i==col) continue;
if(board[row][i]==num) return false;
}
for(int i=0;i<9;i++){
if(i==row) continue;
if(board[i][col]==num) return false;
}
int a=row/3;
int b=col/3;
for(int i=a*3;i<(a+1)*3;i++){
for(int j=b*3;j<(b+1)*3;j++){
if(row==i&&col==j) continue;
if(board[i][j]==num) return false;
}
}
return true;
}
};
相關文章
- 【原創】視訊+文字:詳解VBA解決數獨問題
- [AGC001E] BBQ Hard題解GC
- [題解]CF958C3 Encryption (hard)
- java解數獨Java
- P11059 [入門賽 #27] 數字 (Hard Ver.)題解
- 雙模數問題 題解
- CF1967B2 Reverse Card (Hard Version) 題解
- 一個解數獨的程式
- [題解]CF1990E2 Catch the Mole(Hard Version)
- 題解:CF1537E2 Erase and Extend (Hard Version)
- java解決數字黑洞問題Java
- Acwing166 數獨題解 - DFS剪枝最佳化
- 單獨補題-數正方形
- CF1264D2 Beautiful Bracket Sequence (hard version) 題解Racket
- LeetCode 37. 解數獨LeetCode
- nginx 直播程式數問題(待解決)Nginx
- 解決超過會話數問題會話
- 異地獨生子女結婚怎麼解決父母養老問題?
- JavaScript解決浮點數算數運算精度問題JavaScript
- uniapp js 數獨小遊戲 寫死的簡單數獨 數獨 3.0APPJS遊戲
- 解決「問題」,不要解決問題
- P2404 自然數的拆分問題c++題解C++
- 洛谷P2404 自然數的拆分問題——題解
- P6123 [NEERC2016] Hard Refactoring 題解
- vue 數獨Vue
- 數獨遊戲遊戲
- 關於一個最簡單的數獨解題實現與疑惑一
- 數獨動態解題演示小網站 - 基於Vue/pixi.js/Flask網站VueJSFlask
- 一次數獨生成及解題演算法的剖析(Java實現)演算法Java
- python解數獨的簡單優化Python優化
- js算數運算精度問題解決方案JS
- multidex解決65k方法數問題IDE
- rake 任務引數傳遞問題解決
- WPF 解決 CommandParameter 引數不更新問題
- 透過Treeset解決隨機數排序問題隨機排序
- 解決Url帶中文引數亂碼問題
- 發現問題,解決問題
- [LeetCode 刷題] 4. 尋找兩個有序陣列的中位數 (Hard)LeetCode陣列