C 回溯法 剪枝 求組合數之和

2021-10-03 20:45:51 字數 1843 閱讀 9728

已知一組數(其中有重複元素),求這組數可以組成的所有子集中,子集中的各個元素和為整數target的子集,結果中無重複的子集。

例如:nums=[10,1,2,7,6,1,5], target=8

結果為:[[1,7],[1,2,5],[2,6],[1,1,6]]

該題無論是回溯法或位運演算法,整體時間複雜度為o(2^n)。

為了減小時間複雜度,在搜尋回溯過程中應進行剪枝操作:

遞迴呼叫時,計算已選擇元素的和sum,若sum>target,不再進行更深的搜尋,直接返回。

#include

#include

class

solution;~

solution()

; std::vectorint>> combinationsum2

(std::vector<

int>

& candidates,

int target)

private

:void

generate

(int i, std::vector<

int>

& nums, std::vectorint>>

& result, std::vector<

int> item,

int sum,

int target)

sum +

= nums[i]

; item.

push_back

(nums[i]);

if(sum==target&&

find

(result.

begin()

,result.

end(

),item)

==result.

end())

generate

(i +

1, nums, result, item, sum, target)

; sum -

= nums[i]

; item.

pop_back()

;generate

(i +

1, nums, result, item, sum, target);}

};intmain()

for(

unsigned

int j =

0; j < result[i]

.size()

; j++

)printf

("\n");

}return0;

}

執行結果為:

[1]

[1][

6][1

][2]

[5][

1][7

][2]

[6]

此處若將原來的數進行逆序排序後再進行剪枝回溯也可以。

只需將

std::

sort

(candidates.

begin()

, candidates.

end())

;

改為

std::

sort

(candidates.

rbegin()

, candidates.

rend()

);

改為逆序後的執行結果為:

[7]

[1][

6][2

][6]

[1][

1][5

][2]

[1]

逆元法求組合數

a b p a p b p a b p a p b p a b p a p b p 但是 a b frac ba p amo dpbm od p frac bmodpa modp 這種時候就要用到逆元 在求組合數時 c nm tbinom mn n m n m frac m n m n p n m ...

Leetcode 組合總數II(回溯法 剪枝)

給定乙個陣列 candidates 和乙個目標數 target 找出 candidates 中所有可以使數字和為 target 的組合。candidates 中的每個數字在每個組合中只能使用一次。說明 所有數字 包括目標數 都是正整數。解集不能包含重複的組合。示例 1 輸入 candidates 1...

C 求組合數 再取模

c n,m n n m m c 在處理大數除法的時候好像會出現問題,所以用除法有時候會因為精度不夠沒法得到正確答案.需要把除法變成乘法.知識儲備 逆元 快速冪 逆元 若a x m 1 我們稱x是a的逆元,x寫做a 1 相當於整除中的倒數 那假設我們要求a b m的值,當b特別大時我們無法得到正確答案...