回溯題目集合 貳

2021-10-22 18:47:27 字數 3562 閱讀 9345

給定乙個無重複元素的陣列 candidates 和乙個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。

candidates 中的數字可以無限制重複被選取。

說明:所有數字(包括 target)都是正整數。

解集不能包含重複的組合。

題目鏈結

解析:

1.需要傳遞的引數有:

臨時陣列用來臨時儲存獲得的元素。

二維陣列,當條件滿足時將臨時陣列內的元素拷貝至二維陣列。

計數器,用來統計當前臨時陣列內的元素總和

2.尋找剪枝條件

通過題目知道陣列是無重複元素的,且都是正整數,因此可以得出遞迴出口和剪枝條件,當我們選的陣列的總和等於target時,就可以將臨時陣列內的元素拷貝至二維陣列,當我們臨時陣列內的元素的總和大於target時則可以直接進行剪枝

3.構建遞迴方程

回溯方程通常都有乙個for迴圈來進行每個元素的遍歷,然後我們通過題目可知每個元素都可重複使用,因此每次遞迴for迴圈都可以從前面一樣的起點開始。

又題目是求組合不是求排列,因此我們的解之中不能有重複的答案,怎麼來保證答案不會重複呢?很顯然,當我們以乙個數字作為起點找出含有它的所有答案之後,我們就不再使用它,因此我們的for尋找中給出乙個變數sub,用來儲存我們的起點遍歷的位置,用過乙個起點之後就不再含有這個元素,這樣就保證了我們的答案之中不會有重複的;

void

getnum

(int

* candidates,

int candidatessize,

int target,

int* returnsize,

int*

* returncolumnsizes,

int*

*ret,

int*temp,

int temp_sub,

int count,

int sub)

if(count>target)

//剪枝

return

;for

(int i=sub;i

)//sub保證不會有重複的答案

}int**

combinationsum

(int

* candidates,

int candidatessize,

int target,

int* returnsize,

int*

* returncolumnsizes)

給定乙個陣列 candidates 和乙個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。

candidates 中的每個數字在每個組合中只能使用一次。

說明:所有數字(包括目標數)都是正整數。

解集不能包含重複的組合。

題目鏈結

解析:

此題是上題的變種問題,在引數傳遞方面同樣需要傳遞臨時陣列,二維陣列,計數器。

遞迴出口也是target等於我們計數器的值時便將臨時陣列中的內容拷貝至二維數值之中。

剪枝條件也是當計數器count大於target時直接退出當前遞迴完成剪枝。

在遞迴構建方面,我們同樣需要乙個for迴圈來進行控制,由於每個元素只能使用一次,因此需要乙個for迴圈的控制下標變數sub,每次遞迴sub的值都要+1,保證下一次不會取到同樣的數字。

如此一來,便達成了初步要求,即將所有等於目標值的解都拷貝至陣列之中。

但是現在還有乙個問題,就是我們的陣列之中可能含有相同的元素,因此就算我們控制了下標不會使用,用過的元素,但是當含有相同的元素的時候還是會出現重複的解,我們的解決辦法是將陣列進行排序,並且給定乙個標記陣列,在給臨時陣列賦值時進行判斷,如果當前元素和前乙個元素相等,並且前乙個元素沒有被標記,說明前乙個元素已經被使用過了且進行了回溯,因此我們進行剪枝,將當前元素進行拋棄

能用這種方法排重的原理如下圖所示:

void

getnum

(int

* candidates,

int candidatessize,

int target,

int* returnsize,

int*

* returncolumnsizes,

int*

*ret,

int*temp,

int*flag,

int temp_sub,

int count,

int sub)

for(

int i=sub;i

intcompar

(int

*x,int

*y)int**

combinationsum2

(int

* candidates,

int candidatessize,

int target,

int* returnsize,

int*

* returncolumnsizes)

;getnum

(candidates,candidatessize,target, returnsize,returncolumnsizes,ret,temp,flag,0,

0,0)

;return ret;

}

找出所有相加之和為 n 的 k 個數的組合。組合中只允許含有 1 - 9 的正整數,並且每種組合中不存在重複的數字。

說明:所有數字都是正整數。

解集不能包含重複的組合。

題目鏈結

解析

通過題目可知資訊,組合中只允許1-9個正整數,則可以當作一維陣列不重複的9個元素。

相加之和為n和k個數的組合則是遞迴出口和剪枝條件。

不存在重複的數字,說明進行遞迴時,需要乙個下標變數sub,來保證不會取到重複的值

void

getnum

(int k,

int n,

int* returnsize,

int*

* returncolumnsizes,

int*

*ret,

int*temp,

int count,

int temp_sub,

int sub)

for(

int i=sub;i<

10;i++

)//元素1-9,且不出現重複元素

}int**

combinationsum3

(int k,

int n,

int* returnsize,

int*

* returncolumnsizes)

動態規劃題目集合 貳

給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。你可以認為每種硬幣的數量是無限的。題目鏈結 題目解析 1.動態規劃首先需要知道問題的最後一步是什麼,我們是要求達到總金額x時最少的硬幣總數...

集合 貳 常用方法總結

通過 演示上述方法的使用 import j a.util.arraylist public class arraylistdemo01 arraylist集合相當於是乙個長度可變的陣列,所以訪問集合中的元素也是採用索引方式訪問,第乙個元素儲存在索引0的位置,第二個元素儲存在索引1的位置,依次類推。通...

BFS題目集合

有時間要去做做這些題目,所以從他人空間copy過來了,謝謝那位大蝦啦。解法 bfs,要注意的是如何判斷圖形是一樣的,我的做法就是計算每兩個點的距離之和。看 解法 dfs 簡單題目。pku 1077 eight 解法 廣搜,雙向光搜,a ida 其中 a 時間最好,雙向的廣搜也ok ida 時間500...