目录
讀題
回溯算法理论基础
看完回溯算法理論基礎後,主要有幾個重點
-
效能: 回溯算法本質是窮舉法,就算可以縮小範圍,但本質並非是個高效的算法
-
能解決的問題
- 組合: N個數裡面根據一定規則找出K個數的集合
- 排序: N個數裡面根據一定規則排序,有多少排列方式
- 切割: 字符串按一定規則有幾種切割方式
- 子集: 一個N個數的集合有多少符合條件的子集
- 棋盤: N皇后、解數獨
-
回溯法模板
void backtracking(參數) { if (終止條件) { 存放結果; return; } for(選擇: 本層有多少元素){ 處理節點; backtracking(路徑,選擇列表) \\\\遞迴 回溯,撤銷處理結果 } return; }
-
模板中的for迴圈可以理解為橫向遍歷、遞迴可以理解為縱向遍歷,如下圖(圖來源: 代碼隨想錄)
77. 组合
看完代码随想录之后的想法
看完之後,可能因為有先做二叉樹的題目,所以理解不難,今天在看完解題之後,過了兩三個小時回到電腦前認真做題,因為對於觀念很清晰,所以一般解法以及剪枝的寫法都不難理解
77. 組合 - 實作
思路
未剪枝(未縮小遍歷範圍)
- 建立results儲存結果,建立path建立符合條件的結果
- 建立函數backtracking
- 參數n , k , startindex (startindex 決定下一層由那裡開始)
- 終止條件: 如path的長度 == k 代表已找到組合,將結果放入results 並return
- 單遞迴
- for 橫向遍歷
- 處理當前數值放入path
- backtracking 遞迴,縱向遍歷
- 回溯操作,撤回之前放入的值
- 主函數
- 遞迴
- return results
剪枝(縮小遍歷範圍)
- 建立results儲存結果,建立path建立符合條件的結果
- 建立函數backtracking
- 參數n , k , startindex (startindex 決定下一層由那裡開始)
- 終止條件: 如path的長度 == k 代表已找到組合,將結果放入results 並return
- 單遞迴
- for 橫向遍歷,並且由最多遍歷到長度n,改為"最多”遍歷到n - (k - path.size()) + 1 的長度,+1是因為要包含自己。
- 處理當前數值放入path
- backtracking 遞迴,縱向遍歷
- 回溯操作,撤回之前放入的值
- 主函數
- 遞迴
- return results
代碼
未剪枝(未縮小遍歷範圍)
class Solution {
public:
vector<vector<int>> results;
vector<int> path;
void backtracking(int n, int k, int startindex) {
//終止條件
if( path.size() == k) {
results.push_back(path);
return;
}
//單遞迴
for(int i = startindex; i <= n ; i++){
path.push_back(i);
backtracking(n, k, i + 1); //i + 1 是因為要遞迴i後面的值
path.pop_back(); //回溯操作
}
}
vector<vector<int>> combine(int n, int k) {
backtracking(n, k, 1); //數由1開始,所以要帶入1
return results;
}
};
剪枝(縮小遍歷範圍)
class Solution {
public:
vector<vector<int>> results;
vector<int> path;
void backtracking(int n, int k, int startindex) {
//終止條件
if( path.size() == k) {
results.push_back(path);
return;
}
//單遞迴,n - 目標長度與目前長度的差
for(int i = startindex; i <= n - (k - path.size()) + 1 ; i++){
path.push_back(i);
backtracking(n, k, i + 1); //i + 1 是因為要遞迴i後面的值
path.pop_back(); //回溯操作
}
}
vector<vector<int>> combine(int n, int k) {
backtracking(n, k, 1); //數由1開始,所以要帶入1
return results;
}
};
總結
自己实现过程中遇到哪些困难
今天因為有先聽卡哥講解,所以在理解上沒有遇到太大的困難,只是需要多練習這些題目
今日收获,记录一下自己的学习时长
今天大概學習1.5hr ,整體對於回溯的作法有了新的認知。
相關資料
● 今日学习的文章链接和视频链接
第七章 回溯算法part01
理论基础
题目链接/文章讲解:https://programmercarl.com/回溯算法理论基础.html
视频讲解:带你学透回溯算法(理论篇)| 回溯法精讲!_哔哩哔哩_bilibili
77. 组合
题目链接/文章讲解:https://programmercarl.com/0077.组合.html