一. 八皇后問題
第一種解法將棋盤的所有格仔都初始化為『.』, 定義遞迴函式為前l-1行的格仔已經排好(給定排面的情況下), 從第l層開始繼續排得到的八皇后搜尋結果。具體做法是從第l行的每乙個列逐列嘗試,如果不衝突則加入,再進行l+1的問題求解,求解完後進行回溯。空間複雜度為o(n*n)
classsolutionprivate:
void btsearch(vector> &round, int t, int n, int &total)
for (int i = 0; i < n; i++) }}
bool isok(const vector>round, int t, intj)
for (int r=0; r)
// 45 o
for (int c=t-1, r=j+1; c>=0 && r)
// 135 o
for (int c=t-1, r=j-1; c>=0 && r>=0; c--, r--)
// nqueque = 4。
return true;
}};
classsolutionprivate:
void btsearch(vector> &round, int t, int n, int &total)
for (int i = 0; i < n; i++) }}
bool isok(const vector>round, int t, intj)
for (int r=0; r)
第二種方法類似,不過可以將格仔表示成乙個一維陣列,第i個元素的值j表示將皇后放在第i行第j列
二. permutation
對乙個陣列進行全排列,無重複元素,定義遞迴函式為前i-1個元素全排列已經排好, 將第i個元素以及後面的元素進行全排列。過程為從第i個元素到最後乙個元素輪流放在第i個位置上, 然後對第i+1個元素以及後續元素進行全排列。
classsolutionprivate:
void permutehelper(vector&nums, int l, vector> &res)
for (int i = l; i < nums.size(); i++)
} };
若有重複,則先進行sort, 並且輪流當頭那部分相同的數字只能出現一次,
classsolutionprivate:
void helper(vector& nums, int l, vector> &res)
}};
三. 整數拆分
輸入乙個整數n,輸出這個整數的所有劃分方法,例如對於4,我們可以得到:4、3+1、2+1+1、1+1+1+1這四種劃分方案。
為了使得有相同數字不同順序組成的方案記作一種方案,我們另m表示當前整數劃分方案中最大的數字,cursum表示當前方案已經構成的和,如果cursum==n則輸出當前方案,否則嘗試從m到1加入到方案中,並遞迴呼叫,注意回溯時,需要刪除之前新增的數字。
void intsplitprint(int n, int m, int cursum, vector &cur)cout
<}
else}}
}
四. combinesum
在一組數字中,尋找子陣列,使子陣列的元素和為target的所有組合,求羅列所有組合,或求解組合總數,或求解最少使用的組合中元素個數(找零錢問題leetcode322)
求乙個陣列中所有的和等於target的組合。要求:
1.每個數可以用多次
2.沒有重複的組合
3.乙個組合中的所有的數是公升序排列的
classsolutionvoid btsearch(vectorcandidates, int l, int target, vector&out, vector>&res)
if (target == 0)
for (int i = l ; i< candidates.size(); i++)
}};
五. combinesumii
求乙個陣列中所有的和等於target的組合。要求:
1.每個數最多只能使用一次
2.沒有重複的組合
3.乙個組合中的所有的數是公升序排列的
classsolutionvoid combinationsum2dfs(vector&num, int target, int start, vector&out, vector> &res) }}
};
六. subsets
給定乙個整數的set, 給出所有的子set。無重複數字。每乙個元素有選擇放或者不放兩種選擇。
classsolutionprivate:
void helper(vectornums, int l, vector&out, vector>&res)
out.push_back(nums[l]);
helper(nums, l+1, out, res);
out.pop_back();
helper(nums, l+1, out, res);
}};
回溯演算法的模板整理
回溯演算法的基本模板在很多場合有很重要的作用,一般的回溯問題都是在基本的模板上進行變種解決。回溯演算法在排列組合問題上主要分為不可重複回溯和可重複回溯,如 不可重複回溯 1 2 回溯演算法不可重複 相當於每一層選擇乙個進行排列組合3 param nums4 param temp5 6 in 1 2 ...
遞迴與回溯演算法整理(二)
這是leetcode 上的乙個經典的習題 也是我面試伴魚時碰到的乙個問題 汗 當初沒好好刷題 給你乙個由 1 陸地 和 0 水 組成的的二維網格,請你計算網格中島嶼的數量。島嶼總是被水包圍,並且每座島嶼只能由水平方向或豎直方向上相鄰的陸地連線形成。此外,你可以假設該網格的四條邊均被水包圍。其實這是乙...
回溯 leetcode回溯演算法
回溯演算法實際上乙個類似列舉的搜尋嘗試過程,主要是在搜尋嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就 回溯 返回,嘗試別的路徑。回溯法是一種選優搜尋法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,...