LeetCode_Medium_39. Combination Sum

2019.2.14

祝大家情人节快乐!O(∩_∩)O哈哈~

题目描述:

Given a set of candidate numbers (candidates(without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

The same repeated number may be chosen from candidates unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

Example 1:

Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
  [7],
  [2,2,3]
]

Example 2:

Input: candidates = [2,3,5], target = 8,
A solution set is:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

这题给出一个数组,和一个target,要求求出数组中数字之和等于target的数字,返回结果数组。并且数组中的数可以重复使用。

解法一:

回溯算法,也即DFS遍历,这样就可以把所有可能的情况都返回了。我们用index记录当前遍历到的数组的下标,out记录当前的一个解,res返回所有的解即可。

C++代码:

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int> &candidates, int target) {
        vector<vector<int>> res;
        combinationSumDFS(candidates,target,0,{},res);
        return res;
    }
    void combinationSumDFS(vector<int> &candidates, int target, int index, vector<int> out, vector<vector<int>> &res){
        if(target<0) return ;
        if(target==0) {
            res.push_back(out);
            return;
        }
        for(int i=index;i<candidates.size();i++){
            out.push_back(candidates[i]);
            combinationSumDFS(candidates,target-candidates[i],i,out,res);
            out.pop_back();
        }
    }
};

解法二:

解法一就是最常规的回溯算法,其实我们思考一下,完全可以进行一定的剪枝操作,比如说如果有一个数已经大于target,那么显然不需要考虑这个数了,所以我们先对原数组进行排序,这样一旦遍历到某个数大于target,之后的直接剪掉,或者target已经等于0了,后面的操作也可以剪掉,由此来进行算法的优化。

C++代码:

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int> &candidates, int target) {
        vector<vector<int>> res;
        sort(candidates.begin(), candidates.end());
        for (int i = 0; i < candidates.size(); ++i) {
            if (candidates[i] > target) break;
            else if (candidates[i] == target) {res.push_back({candidates[i]}); continue;}
            vector<int> vec = vector<int>(candidates.begin() + i, candidates.end());
            vector<vector<int>> tmp = combinationSum(vec, target - candidates[i]);
            for (auto a : tmp) {
                a.insert(a.begin(), candidates[i]);
                res.push_back(a);
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_41637618/article/details/87250472