LeetCode—37. 解数独(困难)
生活随笔
收集整理的這篇文章主要介紹了
LeetCode—37. 解数独(困难)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
37. 解數(shù)獨(困難)
題目描述:
編寫一個程序,通過填充空格來解決數(shù)獨問題。
數(shù)獨的解法需 遵循如下規(guī)則:
數(shù)字 1-9 在每一行只能出現(xiàn)一次。
數(shù)字 1-9 在每一列只能出現(xiàn)一次。
數(shù)字 1-9 在每一個以粗實線分隔的 3x3 宮內(nèi)只能出現(xiàn)一次。(請參考示例圖)
數(shù)獨部分空格內(nèi)已填入了數(shù)字,空白格用 ‘.’ 表示。
考察重點:遞歸回溯(DFS)
方法概括:通過36中的判別方法,構(gòu)建row,column,tube進(jìn)行合法性判定,結(jié)合深度優(yōu)先搜索對矩陣中的 ‘.’ 點位遍歷所有可能填入數(shù)字。
public boolean Dfs(int i, int j, char[][] board, boolean[][] row, boolean[][] column, boolean[][] tube){ //后三個參數(shù)分別用來判斷,當(dāng)前位置(i,j)填入一數(shù)字后是否合法int p = i / 3 * 3 + j / 3;for(int a1 = 0;a1 < 9 ;a1 ++){ //遍歷1-9,即該位置可以填入的所有數(shù)字if(!row[i][a1] && !column[j][a1] && !tube[p][a1]){//判斷該位置填入相應(yīng)數(shù)字后,是否負(fù)責(zé)數(shù)獨規(guī)則row[i][a1] = true;column[j][a1] = true;tube[i / 3 * 3 + j / 3][a1] = true;board[i][j] = (char)(a1 + 1 + '0');int tj = j + 1;if (i == 8 && j == 8)return true;for(int ti = i;ti < 9;ti ++) { //當(dāng)前位置填入a1+1后,繼續(xù)尋找并迭代下一個'.'位置for (; tj < 9; tj++) {if (board[ti][tj] == '.') {if (Dfs(ti, tj, board, row, column, tube))return true;ti = 10;break;}if (ti == 8 && tj == 8) //兩處if (ti == 8 && tj == 8)分別用來做遞歸停止條件,即分別為board[8][8]是'.'和數(shù)字的情況return true;}tj = 0; //因為遍歷是從(i,j)開始找下一個,所以此處tj=0是配合循環(huán)實現(xiàn)矩陣遍歷}row[i][a1] = false; //填入a1無法滿足后續(xù)位置滿足條件,則向前回溯column[j][a1] = false;tube[i / 3 * 3 + j / 3][a1] = false;board[i][j] = '.';}}return false;} public void solveSudoku(char[][] board) {boolean[][] row = new boolean[9][9]; // 9個長度為9的判別串。分別用來判斷(i,j)上可以存放的數(shù)字,row[i][a1]=true 表示第i行已經(jīng)存在a1boolean[][] column = new boolean[9][9]; //column[j][a1]=true 表示第j列已經(jīng)存在a1boolean[][] tube = new boolean[9][9];//tube[i / 3 * 3 + j / 3][a1]=true 表示第i / 3 * 3 + j / 3個正方形內(nèi)已經(jīng)存在a1for(int i = 0;i < board.length;i ++)for(int j = 0;j < board[0].length;j ++){ //由于已經(jīng)擁有一些數(shù)字,所以進(jìn)行初始化if(board[i][j] != '.'){int a1 = board[i][j] - '0' - 1;row[i][a1] = true;column[j][a1] = true;tube[i / 3 * 3 + j / 3][a1] = true;}}for(int i = 0;i < board.length;i ++) //尋找迭代起始位置,即第一個'.'for(int j = 0;j < board[0].length;j ++)if(board[i][j] == '.')Dfs(i, j, board, row, column, tube); }總結(jié)
以上是生活随笔為你收集整理的LeetCode—37. 解数独(困难)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10照片查看器不能点下一张的方法
- 下一篇: R语言数据接口(下载、读取、写入)