原题地址(中等)

代码1

直接使用了weiwei 老哥的思路

  1. class Solution {
  2. public:
  3. vector<vector<int>> vv;
  4. vector<int> v;
  5. void dfs(vector<int> candidates, int k, int cur, int end){
  6. if(k < 0) return;
  7. if(k == 0){
  8. vv.push_back(v);
  9. return ;
  10. }
  11. // 回溯
  12. for(int i=cur; i<=end; i++){
  13. v.push_back(candidates[i]);
  14. dfs(candidates, k-candidates[i], i, end);
  15. v.pop_back();
  16. }
  17. }
  18. vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
  19. int n = candidates.size();
  20. if(n==0) return {};
  21. dfs(candidates, target, 0, n-1);
  22. return vv;
  23. }
  24. };

代码2

自己想出来的。回溯嘛,就是两种情况呗。
遇到当前元素时:

  • 把当前元素加入vector,然后继续;
  • 不加当前元素,然后继续;

只不过此题有点稍微不同,那就是在加入当前元素之后,还存在两种选择:

  1. 继续处理当前元素(因为题目允许元素重复)
  2. 处理下一个元素

只不过这个思路和代码1相比,是会产生重复解的,所以我用了set容器。

  1. class Solution {
  2. public:
  3. set<vector<int>> ans; // 进行去重
  4. vector<int> v;
  5. vector<int> nums;
  6. void dfs(int k, int cur, int end){
  7. int sum = 0;
  8. for(auto num : v) sum += num;
  9. //终止条件和减枝
  10. if(sum == k){
  11. ans.insert(v);
  12. return;
  13. }
  14. if(cur > end || sum > k || k - sum < nums[cur]) return;
  15. //递归情况1,加入当前元素
  16. v.push_back(nums[cur]);
  17. dfs(k, cur, end);
  18. dfs(k, cur+1, end);
  19. //情况2,不加当前元素
  20. v.pop_back();
  21. dfs(k, cur+1, end);
  22. }
  23. vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
  24. sort(candidates.begin(), candidates.end());
  25. int n = candidates.size();
  26. nums = candidates;
  27. dfs(target, 0, n-1);
  28. vector<vector<int>> vv(ans.begin(), ans.end());
  29. return vv;
  30. }
  31. };