1. 題目:給定乙個陣列a(a中不存在重複元素)和乙個值k,求出a中元素之和為k的所有組合。比如a為,k=7,則所有組和有2+2+3和7。
2. 解析:回溯+遞迴。比較難以理解的是index索引的使用,**如下:
void printsum(int candidates, int index, intn)
//target:目標值
//sum:已經求得的和
//candidates:候選的數字
//sz:候選數字的個數
//index:記錄被選中的數字的下標
//n:index有效記錄的長度
//index和n是為了記錄選中的候選數字資訊,以便輸出這些符合要求的候選數
void solve(int target, int sum, int candidates, int sz, int index, int
n)
} void solve(int target, int candidates, int
sz)
index記錄選中的元素的下標。需要注意的是for迴圈中的i=index[n],是為了保證每次選擇新的元素都是從下標index[n]之後(包括index[n])開始選擇,不會向前選擇;index[n+1]=i,是說明下乙個元素下標從i開始,i++保證index[n]之後的所有元素都會被選擇。
3. 如果題目變成:a中每個元素只允許使用一次,該怎樣修改**?如輸入10, 1, 2, 7, 6, 3, 5,k=8,輸出為:1 2 5,1 7,2 6,3 5。只需將solve中的index[0]=0改成index[0]=-1,將index[n+1]=i改為index[n+1]=i+1。這樣就保證下一次選擇是從下乙個元素開始的,同乙個元素就會只被選擇一次。
4. 如果a中允許重複元素出現,而輸出結果中不允許出現重複的組合如:1 2 5和1 5 2是重複的組合,這個應該怎樣修改?如果這樣要求,就要將給定的陣列排序,然後使用set儲存最後的結果對,set中不存在重複的元素。**如下:
1//使用這種方式避免重複,前提是candidates必須是已經排好序的2//
因為set>會認為(1,2,5)和(2,1,5)是不同3//
的兩個元素。如果已排序,那麼就不會出現(2,1,5)這樣的無序組合了
4set
int> >combinations;
5void printsum(int candidates, int index, int
n)
1112
//target:目標值
13//
sum:已經求得的和
14//
candidates:候選的數字
15//
sz:候選數字的個數
16//
index:記錄被選中的數字的下標
17//
n:index有效記錄的長度
18//
index和n是為了記錄選中的候選數字資訊,以便輸出這些符合要求的候選數
19void solve(int target, int sum, int candidates, int sz, int index, int
n)
29}
3031
void solve(int target, int candidates, int
sz)
3738
intmain()39;
41int candidates[alength]=;
42int target=8;43
solve(target,candidates,alength);
44set
int> >::iterator iter=combinations.begin();
45while (iter!=combinations.end())
4651 cout<52 iter++;53}
54return0;
55 }
5. 改動之後的題目很符合回溯演算法的特點,一般在**書寫的時候使用vector,更清晰易懂。**如下:
1void printsum(vectorvec) 67
//target:目標值8//
sum:已經求得的和9//
candidates:候選的數字
10//
sz:候選數字的個數
11//
vec:vector儲存已經選擇的元素
12//
startid:從哪個下標對應的元素開始選擇
13//
index和n是為了記錄選中的候選數字資訊,以便輸出這些符合要求的候選數
14void solve(int target, int sum, int candidates, int sz, vector vec, int
startid)
2122
for (int i = startid; i < sz; i++)
27}
2829
void solve(int target, int candidates, int
sz)
同樣的,如果要去除重複的元素,仍然要對陣列進行排序,然後使用set儲存不同的元素。
1268 和為K的組合
給出n個正整數組成的陣列a,求能否從中選出若干個,使他們的和為k。如果可以,輸出 yes 否則輸出 no 收起第1行 2個數n,k,n為陣列的長度,k為需要判斷的和 2 n 20,1 k 10 9 第2 n 1行 每行1個數,對應陣列的元素a i 1 a i 10 6 如果可以,輸出 yes 否則輸...
找出陣列中和為N 1的的所有組合
乙個整數數列,元素取值可能是1 n n是乙個較大的正整數 中的任意乙個數,相同數值不會重複出現。設計乙個演算法,找出數列中符合條件的數對的個數,滿足數對中兩數的和等於n 1。複雜度最好是o n 如果是o n2 則不得分 方法一 排序後,定義兩個指標begin,end分別指向陣列的第乙個和最後乙個元素...
和為K的組合(01揹包)
給出n個正整數組成的陣列a,求能否從中選出若干個,使他們的和為k。如果可以,輸出 yes 否則輸出 no input 第1行 2個數n,k,n為陣列的長度,k為需要判斷的和 2 n 20,1 k 10 9 第2 n 1行 每行1個數,對應陣列的元素aii 1 aii 10 6 output 如果可以...