【leetcode】Combination Sum (middle)

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

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

Note:

  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • The solution set must not contain duplicate combinations.

 

For example, given candidate set 2,3,6,7 and target 7
A solution set is: 
[7] 
[2, 2, 3] 

 

思路: 有规律的查找,避免重复。用递归得到所有的解

class Solution {

public:

    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {

        vector<vector<int>> ans;

        if(candidates.empty())

            return ans;



        sort(candidates.begin(), candidates.end()); //从小到大排序

        recursion(ans, candidates, 0 , target);

        return ans;

    }



    void recursion( vector<vector<int> > &ans, vector<int> candidates, int k, int target)

    {

        static vector<int> partans;

        if(target == 0) //如果partans中数字的总和已经达到目标, 压入答案

        {

            ans.push_back(partans); 

            return;

        }

        if(target < 0)

            return;



        for(int i = k; i < candidates.size(); i++) //当前压入大于等于candidates[k]的数字

        {

            int sum = candidates[i];

            while(sum <= target) //数字可以压入多次,只要和小于等于目标即可

            {

                partans.push_back(candidates[i]);

                recursion(ans, candidates, i + 1, target - sum); //后面只压入大于当前数字的数,避免重复

                sum += candidates[i];

            }

            while(!partans.empty() && partans.back() == candidates[i]) //状态还原

                partans.pop_back();

        }

    }

};

 

其他人更短的递归,用参数来传partans. 省略了状态还原的代码,数字压入多次也采用了递归而不是循环

class Solution {

public:



    void search(vector<int>& num, int next, vector<int>& pSol, int target, vector<vector<int> >& result)

    {

        if(target == 0)

        {

            result.push_back(pSol);

            return;

        }

        if(next == num.size() || target - num[next] < 0)

            return;



        pSol.push_back(num[next]);

        search(num, next, pSol, target - num[next], result);

        pSol.pop_back();



        search(num, next + 1, pSol, target, result);

    }



    vector<vector<int> > combinationSum(vector<int> &num, int target) 

    {

        vector<vector<int> > result;

        sort(num.begin(), num.end());

        vector<int> pSol;

        search(num, 0, pSol, target, result);

        return result;    

    }

};

 

其他人动态规划的代码,还没看,速度并不快, 但很短

class Solution {

public:

    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {

    sort(candidates.begin(), candidates.end());

    vector< vector< vector<int> > > combinations(target + 1, vector<vector<int>>());

    combinations[0].push_back(vector<int>());

    for (auto& score : candidates)

        for (int j = score; j <= target; j++){

            auto sls = combinations[j - score];

            if (sls.size() > 0) {

                for (auto& s : sls)

                    s.push_back(score);

                combinations[j].insert(combinations[j].end(), sls.begin(), sls.end());

            }

        }

    return combinations[target];

}

};

 

你可能感兴趣的:(LeetCode)