【LeetCode】 数相加组合 Combination Sum

描述

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]
]

思路一:递归

定义一个临时vector,然后利用递归的方法从前到后遍历所有元素,已经遍历过的就跳过,就这样循环遍历

Runtime: 8 ms

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> res;
        if(candidates.size() == 0) return res;
        sort(candidates.begin(), candidates.end());
        vector<int> tmp;
        combinationSum(candidates, target, res, tmp, 0);
        return res;
    }
    
    void combinationSum(vector<int>& candidates, int target, vector<vector<int>>& res, vector<int>& tmp, int begin){
        if(!target){
            res.push_back(tmp); //如果target在等于0的时候添加到res,只有target等于0时进入
            return;
        }
        for(int i = begin; i != candidates.size() && target - candidates[i] >= 0; ++i){
            tmp.push_back(candidates[i]);  //加入到tmp中
            combinationSum(candidates, target - candidates[i], res, tmp, i);  //遍历下一个元素,进入递归
            tmp.pop_back();  //跳过上次遍历,开始输入后续元素,直到tmp为空,向后移位继续遍历
        }
    }
};

 

思路二:动态规划 

DP[0] = [[ ]],

DP[j] = DP[j] + (DP[j - score] + tmp)

在j位置的DP元素根据现在的score与j-score位置的数组,每一个相加得到

这样慢慢补充DP[j],直到得到正确答案

运行时间:12 ms

 

class Solution {
public:
    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
    sort(candidates.begin(), candidates.end()); //先对数组进行排序
    vector< vector< vector<int> > > DP(target + 1, vector<vector<int>>()); //初始化DP数组,长度为target + 1
    DP[0].push_back(vector<int>()); // 初始化DP[0]为[[]]
    for (auto& score : candidates)  // 开始遍历给定的数组
        for (int j = score; j <= target; j++){ //从DP的j~target遍历
            auto tmp = DP[j - score];  //找到tmp位置使得tmp + score = j 
            if (tmp.size() > 0) {
                for (auto& s : tmp)
                    s.push_back(score); //将score添加到tmp的每一个元组里
                DP[j].insert(DP[j].end(), tmp.begin(), tmp.end()); //在DP[j]的末尾加入tmp
            }
        }
    return DP[target];
}
};

 

posted @ 2018-10-07 19:11  华不摇曳  阅读(336)  评论(0编辑  收藏  举报