leetcode:combination sum

来源:互联网 发布:梦幻西游淘宝网租号 编辑:程序博客网 时间:2024/06/07 22:48

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 (a1a2, … , 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] 

------------------------------------------------------------------------------------------------------------------------

首先给定的数组元素是升序排列的,结果集合为:res; 中间结果集合为:partRes; 中间结果集合中元素和sum

所以开始时:元素和sum=0, 从第一个元素开始遍历;

partRes.push_back(当前处理元素); sum+=当前处理元素;

当 sum=target时,res.push_back(partRes);

当sum> targe时,弹出partRes中之前加进去的元素;

处理下一个元素;

具体代码如下:

void findSumPath(vector<int> candidates, int index, int sum, vector<int>& partRes, vector<vector<int>>& res, int target){if (sum > target)return;if (sum == target){res.push_back(partRes);return;}for (int i = index; i < candidates.size(); ++i){partRes.push_back(candidates[i]);findSumPath(candidates, i, sum + candidates[i], partRes, res, target);partRes.pop_back();}}vector<vector<int> > combinationSum(vector<int> &candidates, int target) {vector<int> partRes;vector<vector<int>> res;findSumPath(candidates, 0, 0, partRes, res, target);return res;}

法二:

灵感来自于“凑硬币”问题:

vector<vector<int>> combinationSum(vector<int>& candidates, int target){int alen = candidates.size();vector<vector<int>> res;vector<int> partRes;sort(candidates.begin(), candidates.end());process(res, partRes, candidates, alen, 0, target);return res;}void process(vector<vector<int>>& res, vector<int>& partRes, vector<int> arr, int alen, int index, int target){if (index == alen){if (target == 0)res.push_back(partRes);elsereturn;}else{for (int i = 0; arr[index] * i <= target; ++i){for (int j = 0; j < i; j++){partRes.push_back(arr[index]);}process(res, partRes, arr, alen, index + 1, target - arr[index] * i);for (int j = 0; j < i; ++j){partRes.pop_back();}}}}
法三:

class Solution {private:    vector<vector<int> > ret;    vector<int> a;public:    void solve(int dep, int maxDep, int target, vector<int> &cand)    {        if (target < 0)            return;                    if (dep == maxDep)        {            if (target == 0)            {                vector<int> res;                for(int i = 0; i < maxDep; i++)                    for(int j = 0; j < a[i]; j++)                        res.push_back(cand[i]);                ret.push_back(res);            }            return;        }                for(int i = 0; i <= target / cand[dep]; i++)        {            a[dep] = i;            solve(dep + 1, maxDep, target - cand[dep] * i, cand);        }    }        vector<vector<int> > combinationSum(vector<int> &candidates, int target) {        // Start typing your C/C++ solution below        // DO NOT write int main() function        sort(candidates.begin(), candidates.end());                a.resize(candidates.size());        ret.clear();        if (candidates.size() == 0)            return ret;                    solve(0, candidates.size(), target, candidates);                return ret;    }};





0 0