編寫乙個程式,通過填充空格來解決數獨問題。
乙個數獨的解法需遵循如下規則:
以下內容來自37. 解數獨:【回溯搜尋演算法】詳解
回溯三部曲
遞迴函式以及引數
遞迴函式的返回值需要是bool型別,為什麼呢?
因為解數獨找到乙個符合的條件(就在樹的葉子節點上)立刻就返回,相當於找從根節點到葉子節點一條唯一路徑,所以需要使用bool返回值。
bool
backtracking
(vectorchar
>>
& board)
遞迴終止條件
本題遞迴不用終止條件,解數獨是要遍歷整個樹形結構尋找可能的葉子節點就立刻返回。
不用終止條件會不會死迴圈?
遞迴的下一層的棋盤一定比上一層的棋盤多乙個數,等數填滿了棋盤自然就終止(填滿當然好了,說明找到結果了),所以不需要終止條件!
那麼有沒有永遠填不滿的情況呢?
這個問題我在遞迴單層搜尋邏輯裡在來講!
遞迴單層搜尋邏輯
在樹形圖中可以看出我們需要的是乙個二維的遞迴(也就是兩個for迴圈巢狀著遞迴)
乙個for迴圈遍歷棋盤的行,乙個for迴圈遍歷棋盤的列,一行一列確定下來之後,遞迴遍歷這個位置放9個數字的可能性!
**如下:(詳細看注釋)
bool
backtracking
(vectorchar
>>
& board)
}return
false
;// 9個數都試完了,都不行,那麼就返回false}}
return
true
;// 遍歷完沒有返回false,說明找到了合適棋盤位置了
}
注意這裡return false
的地方,這裡放return false
是有講究的。
因為如果一行一列確定下來了,這裡嘗試了9個數都不行,說明這個棋盤找不到解決數獨問題的解!
那麼會直接返回, 這也就是為什麼沒有終止條件也不會永遠填不滿棋盤而無限遞迴下去!
判斷棋盤是否合法有如下三個維度:
同行是否重複
同列是否重複
9宮格里是否重複
**如下:
bool
isvalid
(int row,
int col,
char val, vectorchar
>>
& board)
}for
(int j =
0; j <
9; j++)}
int startrow =
(row /3)
*3;int startcol =
(col /3)
*3;for
(int i = startrow; i < startrow +
3; i++)}
}return
true
;}
整體**如下:
class
solution
}return
false
;// 9個數都試完了,都不行,那麼就返回false}}
return
true
;// 遍歷完沒有返回false,說明找到了合適棋盤位置了
}//根據數獨的規則, 判斷該位置的字元是否有效
bool
isvalid
(int row,
int col,
char val, vectorchar
>>
& board)
}for
(int j =
0; j <
9; j++)}
int startrow =
(row /3)
*3;int startcol =
(col /3)
*3;for
(int i = startrow; i < startrow +
3; i++)}
}return
true;}
public
:void
solvesudoku
(vectorchar
>>
& board)
};
回溯演算法複雜度如何分析呢?
複雜度分析
37. 解數獨:【回溯搜尋演算法】詳解
leetcode 37 解數獨 深搜
編寫乙個程式,通過已填充的空格來解決數獨問題。乙個數獨的解法需遵循如下規則 數字 1 9 在每一行只能出現一次。數字 1 9 在每一列只能出現一次。數字 1 9 在每乙個以粗實線分隔的 3x3 宮內只能出現一次。空白格用 表示。public class 37 for int i 0 i 9 i fo...
LeetCode37 解數獨(回溯 set)
編寫乙個程式,通過已填充的空格來解決數獨問題。乙個數獨的解法需遵循如下規則 數字 1 9 在每一行只能出現一次。數字 1 9 在每一列只能出現一次。數字 1 9 在每乙個以粗實線分隔的 3x3 宮內只能出現一次。空白格用 表示。row set range 1,10 for in range 9 行剩...
leetcode系列 演算法 困難 解數獨
前段時間碰巧寫了乙個,直接拿來用了 解題思路參考 雜記 數獨求解 因為要適配本題的格式,稍微做了修改 class solution 判斷是否是有效的數獨 def is valid self,row,column,rect num rect num row 3 3 column 3 if self.s...