給定一個無重複元素的數組 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和爲 target 的組合。candidates 中的數字可以無限制重複被選取。
說明:
- 所有數字(包括 target)都是正整數。
- 解集不能包含重複的組合。
示例 1:
輸入: candidates = [2,3,6,7], target = 7,
所求解集爲:
[
[7],
[2,2,3]
]
解題思路:使用遞歸+回溯,爲了避免組合出現重複,例如示例1中的重複組合[2,2,3]和[3,2,2],可以先對輸入candidates進行排序,然後在遞歸的時候,設temp爲當前組合,下一個可以放進temp中的數,一定大於等於temp[-1]。
其Python3代碼如下:
# Python3
class Solution:
def __init__(self):
self.ans = []
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
if not candidates:
return []
def combSums(candidates,target,temp,sums):
if target == sums: # 遞歸停止條件
self.ans.append(temp[:])
return
for n in candidates: # 遍歷每種情況
if sums + n > target: # 如果當前sums值大於target,直接break
break
if temp and n < temp[-1]: # 如果當前輸入的值小於temp[-1]則continue
continue
temp.append(n)
combSums(candidates,target,temp,sums+n)
temp.pop() # 回溯
candidates.sort() # 執行遞歸時先進行排序
combSums(candidates,target,[],0)
return self.ans
其C++代碼如下:
# C++
class Solution {
private:
vector<vector<int>> num;
vector<int> sum;
int i = 0;
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target)
{
sort(candidates.begin(),candidates.end());
function(candidates,target,sum,i);
return num;
}
void function(vector<int>& candidate, int target,vector<int> sum,int i)
{
if(target==0)
{
num.push_back(sum);
}
for(;i<candidate.size();++i) # 只遍歷比當前數字大的candidates數字
{
if(candidate[i]<=target)
{
sum.push_back(candidate[i]);
function(candidate,target-candidate[i],sum,i);
sum.pop_back();
}
}
}
};