backtrack-回溯搜索算法总结
backtrack——回溯算法總結(jié)
這幾天著重在刷LeetCode有關(guān)回溯搜索算法的題,之前也寫了一些博客,感覺當(dāng)時(shí)清楚,但是原理上還是有點(diǎn)模糊。之前根據(jù)別人的模板,依葫蘆畫瓢,解決了一些問題,但是有的時(shí)候條件變了,就有點(diǎn)理不清楚了,特別是哪里該加一些限制條件,很懵逼。所以總結(jié)了一下。
1. 到底什么是回溯?
回溯算法,都知道是基于遞歸的算法。那為什么要用遞歸呢,可以用傳統(tǒng)的寫法代替嘛?之所以用遞歸,就是因?yàn)槿绻脗鹘y(tǒng)的方式,很難寫或者根本寫不出來。舉個(gè)例子,比如我們想知道用集合nums = [1, 2, 3]中的三個(gè)數(shù)字(可重復(fù))一共能構(gòu)成多少個(gè)不同的三位數(shù),學(xué)過排列組合的都知道一共有27(3的3次方)種:(1,1,1), (1,1,2), (1,1,3), (2,1,1), (2,1,2), (2,1,3)…(3,3,3) 。用最傳統(tǒng)的方式,都會(huì)寫,用一個(gè)三層的for循環(huán)來寫:
vector<vector<int>> res; vector<int> path; for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {for (int k = 0; k < 3; k++) {path.push_back({ nums[i], nums[j], nums[k] });res.push_back(path);}} }這個(gè)例子中,集合中的元素還很少。那么如果集合中有100個(gè)元素呢?傳統(tǒng)方式是不是要寫100層循環(huán)?1000呢?因此,這種情況下單靠循環(huán)是完成不了的。這種情況下,就需要遞歸出場了。上面的代碼可以寫為如下遞歸的形式:
vector<vector<int>> res; vector<int> path; void backtrack_0(vector<int>& nums, vector<vector<int>> &res) {if (path.size() == nums.size()) {res.push_back(path);return;}// elsefor (int i = 0; i < nums.size(); i++) {path.push_back(nums[i);backtrack_0(nums, res);path.pop_back();} }上面的代碼中,path的長度其實(shí)就是循環(huán)的深度,回溯遞歸里的每一層其實(shí)都是一個(gè)循環(huán);而else部分,則相當(dāng)于每層循環(huán)的方式(每層for循環(huán)該怎么寫)。遞歸其實(shí)就模擬了上訴過程。
如果題目變成了三個(gè)數(shù)字加起來能構(gòu)成不同的和的情況有多少(就是前面用過的數(shù),后面不能再用。比如:112和211的和就是一樣的)?那么該怎么改呢?
傳統(tǒng)的寫法:
對應(yīng)的遞歸寫法:
vector<vector<int>> res; vector<int> path; void backtrack_1(vector<int>& nums, vector<vector<int>> &res, int idx) {if (path.size() == nums.size()) {res.push_back(path);return;}// elsefor (int i = idx; i < nums.size(); i++) {path.push_back(nums[i);backtrack_1(nums, res, i);path.pop_back();} }最后的輸出都一樣:[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 2, 3], [1, 3, 3], [2, 2, 2], [2, 2, 3], [2, 3, 3], , [3, 3, 3]。
同時(shí),從這里可以看到:循環(huán)的起始范圍變了:從0變成了上層循環(huán)的循環(huán)變量;而在回溯函數(shù)中,循環(huán)的起始值也從0變?yōu)榱?strong>idx。說明,回溯跟多層循環(huán)有著非常密切的關(guān)系!終止條件跟循環(huán)層數(shù)有關(guān)系,遞歸函數(shù)里面的循環(huán)跟每層循環(huán)又有著非常緊密的聯(lián)系!
總結(jié)
以上是生活随笔為你收集整理的backtrack-回溯搜索算法总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机组成原理 精选习题集
- 下一篇: “睡服”面试官系列第五篇之proxy(建