[LeetCode] Combination Sum

Combination Sum

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] 

Solution:

#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;

vector<int* >* preRes;

vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
        //bubble sort candidates
        for(int i = 0;i < candidates.size();i++)
        {
            bool continueBubble = false;

            for(int j = 0;j < candidates.size() - i - 1;j++)
            {
                if(candidates[j] > candidates[j + 1])
                {
                    int tmp = candidates[j];
                    candidates[j] = candidates[j + 1];
                    candidates[j + 1] = tmp;
                    continueBubble = true;
                }
            }

            if(continueBubble == false)
                break;
        }
        preRes = new vector<int* >[target + 1];

        vector<vector<int> > ans;
        if(candidates.size() == 0) return ans;

        for(int i = 1;i <= target;i++)
        {
            //test all the possible candidates.current target is i
            vector<int* > curCom;

            for(int j = 0;j < candidates.size();j++)
            {
                int num = i - candidates[j];
                //if we use one candidates[j], the remain number should be computed already.
                if(num == 0)
                {
                    int* cur = new int[candidates.size()];
                    memset(cur, 0, candidates.size() * sizeof(int));
                    cur[j] = 1;
                    curCom.push_back(cur);
                }
                else if(num > 0 && preRes[num].size() > 0)
                {
                    //new combination comes
                    for(int k = 0;k < preRes[num].size();k++)
                    {
                        int* cur = new int[candidates.size()];
                        for(int t = 0; t < candidates.size();t++)
                            cur[t] = preRes[num][k][t];
                        
                        cur[j]++;

                        bool shouldAdd = true;
                        for(int t = 0; t < curCom.size();t++)
                        {
                            bool isDup = true;
                            for(int s = 0; s < candidates.size();s++)
                            {
                                if(cur[s] != curCom[t][s])
                                {
                                    isDup = false;
                                    break;
                                }
                            }
                            if(isDup)
                            {
                                shouldAdd = false;
                                break;
                            }
                        }
                        if(shouldAdd)
                            curCom.push_back(cur);
                    }
                }
            }
            preRes[i] = curCom;

//            cout << i << " num = " << curCom.size() << endl;
        }

        for(int i = 0;i < preRes[target].size();i++)
        {
            vector<int> vec;
            for(int j = 0;j < candidates.size();j++)
                for(int k = 0;k < preRes[target][i][j];k++)
                    vec.push_back(candidates[j]);
            ans.push_back(vec);
        }

        return ans;        
    }

int main()
{
    vector<int> cand;
    cand.push_back(5);
    cand.push_back(3);
    cand.push_back(2);
    cand.push_back(7);

    vector<vector<int> > ans = combinationSum(cand, 20);

    cout << "results: " << endl;
    for(int i = 0;i < ans.size();i++)
    {
        for(int j = 0;j < ans[i].size();j++)
            cout << ans[i][j] << " ";
        cout << endl;
    }


    return 0;
}
原文地址:https://www.cnblogs.com/changchengxiao/p/3826559.html