39.组合总和
思路:dfs,但是需要注意进行剪枝操作。
class Solution {
public:
vector<vector<int>> v;
vector<int > tmp,copy_candidates;
int tg;
void dfs(int u,int sum){
if(u<0||sum > tg) return;
if(sum == tg){
v.push_back(tmp);
return ;
}
tmp.push_back(copy_candidates[u]);
dfs(u,sum+copy_candidates[u]);//可多次选取
tmp.pop_back();
dfs(u-1,sum);//不选了
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target){
copy_candidates=candidates;
tg=target;
dfs(candidates.size()-1,0);//第一个数是正在遍历的数组下标,第二个数是总和
return v;
}
};
思考:这道题找的是组合数。
1.如果只返回组合数的个数,相当于完全背包问题,直接用dp做就可以。
2.这里需要返回所有可能的组合,那么我们就不能用dp去做,而是通过dfs,这样就可以保存所选的元素。
3.这里使用的dfs里,解决“同一个数字”可使用多次的地方是通过dfs(u,sum+copy_candidates[u])函数实现的,因为这里无重复元素的出现,所以可以放心大胆的用。但如果有重复的数字,那么我们就先对candidates数组进行一下去重操作即可。这样就避免了重复的组合。