题目:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:
输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
题目来源:https://leetcode-cn.com/problems/combination-sum
思路:
1、这是一道深度优先搜索的题目。对于候选数组,每一个元素均有选取和不选取两种可能,首先假设其选取,则接着递归函数选取下一个元素,直至求和等于目标值,如果一直递归到最后也没有合适的结果,说明最后一个元素不该选取,则将其退出,接着选取其他的元素。
2、这个题目有两个难点,一个是不停的递归选取元素,递归放入元素后的匹配条件设置和跳出条件设置。还有一个难点是需要设置返回条件,如果匹配成功则保存并返回结果。
C++代码:
class Solution {
vector<vector<int>> ret; // 最终返回结果
vector<int> temp; // 其中的一个结果
void dfs(int index, int sum, vector<int>& candidates, int target){
int item = candidates[index];
if (index==candidates.size()-1){ // 如果是最后一个元素,判断这个元素能否满足要求
if((target-sum)%item==0){
for (int i=0; i<(target-sum)/item; i++){
temp.push_back(item);
}
ret.push_back(temp);
}
}else{
while(true){ // 递归的插入下一个元素,如果找到则会在前面push放进去,如果没找到则会在下面break
dfs(index+1,sum,candidates,target); // 必须先执行dfs再执行下面的操作,因为下面的可能不会执行到
sum += item;
temp.push_back(item);
if (sum>target)
break;
}
}
// 如果temp中最后一个元素是当前的元素,就把它去掉
while (temp.size()>0 && temp[temp.size()-1]==item){
temp.pop_back();
}
}
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
dfs(0,0,candidates,target);
return ret;
}
};