39. Combination Sum

Given a set of candidate numbers (C) (without duplicates) 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.
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]
]

这仍然是一个递归回溯问题,遵循以下几个步骤:

这里写图片描述

1)按照测试用力画出递归树(注意递归过程的变化);

2)根据递归的变的部分抽象出递归所用参数;

3)在递归树中考虑清楚递归终止条件和递归过程。

解题代码

class Solution {

private:

    vector<vector<int>> res;

    void generateCombinations(vector<int>& candidates, int start, int target, vector<int> &c){

        if (start == candidates.size()) return; // 遍历完了,退出

        // 递归终止,找到组合的情况
        if (target == 0){
            res.push_back(c);
            return;
        }

        // 递归过程
        for (int i = start; i < candidates.size(); i++){

            // 考察当前元素有没有可能放到答案中,当前考察元素已经超过target直接考察下一个元素
            if (target < candidates[i]) continue;

            c.push_back(candidates[i]);

            // 递归过程:因为可重复取值,因此还是尝试从i开始继续寻找
            generateCombinations(candidates, i, target - candidates[i], c);

            c.pop_back(); // 递归回溯,为下一次递归推入做准备

        }
        return;
    }


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

        res.clear();

        // 边界条件
        if (candidates.empty()) return res;

        vector<int> c;
        generateCombinations(candidates, 0, target, c);

        return res;
    }
};

测试代码

class TestHelper{
    Solution s;
public:
    void run(){

        int candiate[] = {8,7,4,3},target = 11;

        vector<int> vec(candiate, candiate + 4);
        Utils::showVecInfo(vec);

        vector<vector<int>> res = s.combinationSum(vec, target);

        // 显示结果信息
        Utils::showVecInfo(res);
    }
};

所用到的工具

namespace Utils {


    // 显示vector信息
    void showVecInfo(vector<int> & v) {

        cout << endl << "vector : [ ";
        for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << *it << " ";
        }
        cout << " ]" << endl;

    }

    // 显示vector信息
    void showVecInfo(vector<vector<int>> & v) {

        cout << endl << "vector<vector<int>> : " << endl;
        cout << "\t\t\t[" << endl;
        for (vector<vector<int>>::iterator iter = v.begin(); iter != v.end(); iter++){

            vector<int> combination = *iter;
            cout << "\t\t\t  [ ";
            for (vector<int>::iterator it = combination.begin(); it != combination.end(); it++)
            {
                cout << *it << " ";
            }
            cout << "]" << endl;
        }
        cout << "\t\t\t]" << endl;
    }

}

运行结果

vector : [ 8 7 4 3  ]

vector<vector<int>> :
                        [
                          [ 8 3 ]
                          [ 7 4 ]
                          [ 4 4 3 ]
                        ]
请按任意键继续. . .
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值