回溯、递归系列

来源:互联网 发布:怎么做好淘宝手机端 编辑:程序博客网 时间:2024/05/18 21:39

数字组合1

给出一组候选数字(C)和目标数字(T),找到C中所有的组合,使找出的数字和为T。C中的数字可以无限制重复被选取。

例如,给出候选数组[2,3,6,7]和目标数字7,所求的解为:

[7],

[2,2,3]

注意事项
所有的数字(包括目标数字)均为正整数。
元素组合(a1, a2, … , ak)必须是非降序(ie, a1 ≤ a2 ≤ … ≤ ak)。
解集不能包含重复的组合。

样例
给出候选数组[2,3,6,7]和目标数字7

返回 [[7],[2,2,3]]

class Solution {public:    /*     * @param candidates: A list of integers     * @param target: An integer     * @return: A list of lists of integers     */    vector<vector<int>> combinationSum(vector<int> &candidates, int target) {        // write your code here        vector<vector<int> > res;        vector<int> temp;        recursive(candidates,target,0,res,temp);        return res;    }    void recursive(vector<int> &candidates, int target, int cur,vector<vector<int> > &res,vector<int> temp){        if(target < 0) return;        else if(target == 0){            res.push_back(temp);        }        else{            int n = candidates.size();            //i从cur开始,不是从0开始            for(int i = cur; i < n; ++i){                temp.push_back(candidates[i]);                recursive(candidates,target-candidates[i],i,res,temp);                temp.pop_back();            }        }    }};

数字组合2

给出一组候选数字(C)和目标数字(T),找出C中所有的组合,使组合中数字的和为T。C中每个数字在每个组合中只能使用一次。

注意事项
所有的数字(包括目标数字)均为正整数。
元素组合(a1, a2, … , ak)必须是非降序(ie, a1 ≤ a2 ≤ … ≤ ak)。
解集不能包含重复的组合。

样例
给出一个例子,候选数字集合为[10,1,6,7,2,1,5] 和目标数字 8 ,
解集为:[[1,7],[1,2,5],[2,6],[1,1,6]]

class Solution {public:    /*     * @param num: Given the candidate numbers     * @param target: Given the target number     * @return: All the combinations that sum to target     */    vector<vector<int>> combinationSum2(vector<int> &num, int target) {        // write your code here        vector<int> tempCom;        set<vector<int> > res;        sort(num.begin(),num.end());        recursive(num,target,0,tempCom,res);        return vector<vector<int> >(res.begin(),res.end());    }private:    void recursive(vector<int> &num, int target, int index,vector<int> tempCom, set<vector<int> > &res){        if(index == num.size()){            if(target == 0){                res.insert(tempCom);            }            return;        }        if(target == 0){            res.insert(tempCom);            return;        }        else if(target < 0) return;        else{            for(int i = index; i < num.size(); ++i){                tempCom.push_back(num[i]);                recursive(num,target-num[i],i+1,tempCom,res);                tempCom.pop_back();            }        }    }};

组合

组给出两个整数n和k,返回从1……n中选出的k个数的组合。
样例
例如 n = 4 且 k = 2

返回的解为:

[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4]]

class Solution {public:    /*     * @param n: Given the range of numbers     * @param k: Given the numbers of combinations     * @return: All the combinations of k numbers out of 1..n     */    vector<vector<int>> combine(int n, int k) {        // write your code here        vector<vector<int> > res;        vector<int> temp;        combine(n,k,1,temp,res);        return res;    }private:    void combine(int n, int k, int cur, vector<int> temp, vector<vector<int> > &res){        if(temp.size() == k){            res.push_back(temp);            return;        }        if(cur > n || temp.size() > k) return;        for(int i = cur; i <= n; ++i){            temp.push_back(i);            combine(n,k,i+1,temp,res);            temp.pop_back();        }    }};