回溯、遞歸系列

數字組合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();
        }
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章