演算法整理 回溯

2022-08-01 20:51:15 字數 2662 閱讀 8152

一.  八皇后問題

第一種解法將棋盤的所有格仔都初始化為『.』,  定義遞迴函式為前l-1行的格仔已經排好(給定排面的情況下), 從第l層開始繼續排得到的八皇后搜尋結果。具體做法是從第l行的每乙個列逐列嘗試,如果不衝突則加入,再進行l+1的問題求解,求解完後進行回溯。空間複雜度為o(n*n)

classsolution 

private:

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;

}};

classsolution 

private:

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個元素以及後續元素進行全排列。

classsolution 

private:

void permutehelper(vector&nums, int l, vector> &res)

for (int i = l; i < nums.size(); i++)

} };

若有重複,則先進行sort, 並且輪流當頭那部分相同的數字只能出現一次,

classsolution 

private:

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.乙個組合中的所有的數是公升序排列的

classsolution 

void 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.乙個組合中的所有的數是公升序排列的

classsolution 

void combinationsum2dfs(vector&num, int target, int start, vector&out, vector> &res) }}

};

六. subsets

給定乙個整數的set, 給出所有的子set。無重複數字。每乙個元素有選擇放或者不放兩種選擇。

classsolution 

private:

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回溯演算法

回溯演算法實際上乙個類似列舉的搜尋嘗試過程,主要是在搜尋嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就 回溯 返回,嘗試別的路徑。回溯法是一種選優搜尋法,按選優條件向前搜尋,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,...