LeetCode算法题11:递归和回溯-解数独
文章目錄
- 解數獨
- 回溯 :
- 僅僅在實現方式上有區別
- 總結
解數獨
??????題目鏈接:https://leetcode-cn.com/problems/sudoku-solver/
??????題目描述:編寫一個程序,通過填充空格來解決數獨問題。
數獨的解法需 遵循如下規則:
數字 1-9 在每一行只能出現一次。
數字 1-9 在每一列只能出現一次。
數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。(請參考示例圖)
數獨部分空格內已填入了數字,空白格用 ‘.’ 表示。
回溯 :
??????思路,運用回溯算法的思想,在 N 皇后問題的基礎上主要解決一個問題:如何描述限制條件?每次在一個位置上放置元素時,需要滿足同行同列和所在九宮格內沒有重復元素,那么可以用 Set 集合來描述這個限制條件。
??????所以回溯類型的題目都不能判斷出當前解是否為最優解,而是只能得到一個合適的解,對于本題而言,已明確告訴僅有一個唯一解,所以直接結束即可。參考代碼如下(帶注釋):
?????? 有些東西需要說明:上面算法中,若是去掉全局變量 f 和相關的語句的話,程序執行完畢之后,board 的值就會又變為初始狀態,狀態變化為:初始狀態 -> 找到唯一解 -> 又回到初始狀態。并且程序在接下來做的工作為"試圖找到下一個可行的解“,但實際上并沒有可行的解了,所做的均是無用功。 本題和之前的回溯算法對比,比如 N-皇后問題,區別在于是否只有一個唯一解,但這也不是最大的區別,最大的區別在于 N-皇后這些問題在找到一個可能的解之后是將該解保存下來了,而本題沒有采用這種做法,雖然也可以這樣做,但沒必要(沒必要浪費時間)。
?????? 加上 f 之后,因為不再執行賦值語句了,所以 board 中的元素一直都保持唯一解不變,并且三個集合也不會在移出元素,所以后面的 for 循環會找不到任何一個可行的 k ,程序便會由此一步步退出。其實直接加上 break 語句更好,這樣后面的 for 循環直接得不到執行的機會了,更加省事,如上面代碼所示。
僅僅在實現方式上有區別
??????此文鏈接:https://mp.weixin.qq.com/s?__biz=MzAxODQxMDM0Mw==&mid=2247492800&idx=2&sn=47bf7232fe5fd533aaf683850f3bd5c7&scene=21#wechat_redirect 它和自己實現的代碼在思想基本差不多,但是其代碼實現方式可供參考借鑒。如下:
public void solveSudoku(char[][] board) {backtrack(board,0,0);//從位置(0,0)開始判斷}boolean backtrack(char[][] board, int i, int j) {int m = 9, n = 9;if (j == n) {// 窮舉到最后一列的話就換到下一行重新開始。return backtrack(board, i + 1, 0);}if (i == m) {// 找到一個可行解,觸發 base casereturn true;}if (board[i][j] != '.') {// 如果有預設數字,不用我們窮舉return backtrack(board, i, j + 1);}for (char ch = '1'; ch <= '9'; ch++) {// 如果遇到不合法的數字,就跳過if (!isValid(board, i, j, ch))continue;board[i][j] = ch;// 如果找到一個可行解,立即結束if (backtrack(board, i, j + 1)) {return true;}board[i][j] = '.';}// 窮舉完 1~9,依然沒有找到可行解,此路不通return false;}boolean isValid(char[][] board, int r, int c, char n) {for (int i = 0; i < 9; i++) {// 判斷行是否存在重復if (board[r][i] == n) return false;// 判斷列是否存在重復if (board[i][c] == n) return false;// 判斷 3 x 3 方框是否存在重復if (board[(r/3)*3 + i/3][(c/3)*3 + i%3] == n)return false;}return true;}總結
??????對了,還有本題的官方題解可供參考,自己實現的代碼時間復雜度有點高…
總結
以上是生活随笔為你收集整理的LeetCode算法题11:递归和回溯-解数独的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode算法题10:DFS/BF
- 下一篇: LeetCode算法题12:递归和回溯-