Combination Sum

给出待选数字集合和目标值,要求得到所有的和为目标值的子集;

例如 待选数字集合{ 2,3,6,7 },目标值7 ,=> { {2,2,3},{7} }

可用递归,则递推式为:f([2,3,6,7],7)={{2+f([2,3,6,7],5)},{3+f([3,6,7],4)},{6+f([6,7],1)},{7+f([7],0)}}

python:

class Solution:
    # @param candidates, a list of integers
    # @param target, integer
    # @return a list of lists of integers
    def combinationSum(self, candidates, target):
        candidates.sort()
        if target<candidates[0]:
            return []
        num_items=len(candidates)
        res=[]
        for i in range(num_items):
            if candidates[i]>target:
                break
            if candidates[i]==target:
                res.append( [candidates[i]] )
                break

            temp=self.combinationSum(candidates[i:num_items],target-candidates[i])#可以再调用candidates[i],但不能掉用i前面的,会出现重复
            for j in temp:
                j.append(candidates[i])
                j.sort()# ...
                res.append(j)
        return res

if __name__ == '__main__':
    s=Solution()
    print(s.combinationSum([2,3,6,7],7))

C++

class Solution {
public:

    vector<vector<int> > combinationSum_in(vector<int> &candidates, int target) {
        vector<vector<int> > res;
        if (candidates.size() <= 0 || target < candidates[0]){
            return res;
        }
        for (int i = 0; i < candidates.size(); ++i){
            vector<int>::iterator it = candidates.begin();// 选出后面的candidate,这样就不要剔除结果中的重复项;
            for (int k = 0; k < i; ++k) ++it;             // 若 combinationSum_in(candidates, target - candidates[i]);
            vector<int> candi(it,candidates.end());       // 则最后要剔除重复项

            vector<vector<int> > res_temp = combinationSum_in(candi, target - candidates[i]);
            if (!res_temp.empty()){
                for (int j = 0; j < res_temp.size(); ++j){
                    res_temp[j].insert(res_temp[j].begin(), candidates[i]);
                    res.push_back(res_temp[j]);
                }
            }
            else if (target == candidates[i]){
                res.push_back({ target });
            }
        }
        return res;
    }

    vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
        sort(candidates.begin(), candidates.end());  //先对待选集合从小到大排序,单独出来是为了不要每次都排一次
        vector<vector<int> > res = combinationSum_in(candidates, target);
        return res;
    }
};
原文地址:https://www.cnblogs.com/iois/p/4023977.html