組み合わせ和問題、leetcode77、216、39、40

 リートコード77

2 つの整数 n と sum を指定するとk、  範囲内の数値の[1, n] 可能なすべての 組み合わせを返します。回答は任意の順序kで返すことができます  。

入力: n = 4、k = 2
出力: 
[ 
  [2,4]、
  [3,4]、
  [2,3]、[ 
  1,2]、
  [1,3]、
  [1,4]、
]
class Solution {
public:
    vector<vector<int>> res;//返回的答案
    vector<int> temp;//符合条件的某一路径

    vector<vector<int>> combine(int n, int k) {
        backtracking(n,k,1);
        return res;
    }
    void backtracking(int n, int k,int start){//start参数保证不重复选取
    if(temp.size()==k){
        res.push_back(temp);
        return;
    }
    for(int i=start;i<= n;i++){
        //在集合n中⾄多要从该起始位置 : n - (k - temp.size()) + 1,开始遍历
        temp.push_back(i);
        backtracking(n,k,i+1);//递归
        temp.pop_back();//回溯
    }
    }
};

 

リートコード 216

合計すると n になる k 個の数値のすべての組み合わせを見つけます。組み合わせには 1 ~ 9 の正の整数のみが使用でき、各組み合わせで数字を繰り返すことはできません。

例証します:

  • すべての数値は正の整数です。
  • ソリューション セットには重複した組み合わせを含めることはできません。

例 1: 入力: k = 3、n = 7 出力: [[1,2,4]]

例 2: 入力: k = 3、n = 9 出力: [[1,2,6]、[1,3,5]、[2,3,4]]

class Solution {
public:
    vector<vector<int>> res;
    vector<int> temp;
    int sum=0;
    vector<vector<int>> combinationSum3(int k, int n) {
        // res.clear(); // 可以不加
        // temp.clear();
        backtracking(k,n,1);
        return res;
    }

    void backtracking(int k, int n,int start){
        //if(sum>n) return;
        if(temp.size()==k){
            if(sum==n) res.push_back(temp);
            return;//个数等于k,但是sum不符合直接return
        }
        for(int i=start;i<=9;i++){
            temp.push_back(i);
            sum+=i;
            backtracking(k,n,i+1);//这里要是或者i+1,用++i,
            temp.pop_back();
            sum-=i;
        }
    }
};

 リートコード39

繰り返し要素のない配列候補とターゲット数値ターゲットが与えられた場合、数値の合計がターゲットになる候補内のすべての組み合わせを見つけます。

候補の数字は無制限に繰り返し選択できます。

例証します:

  • すべての数値 (ターゲットを含む) は正の整数です。
  • ソリューション セットには重複した組み合わせを含めることはできません。
  • 入力例: 候補 = [2,3,6,7]、ターゲット = 7、
  • 解決されたセットは次のとおりです: [ [7], [2,2,3] ]
class Solution {
public:
    vector<vector<int>>  res;
    vector<int> s;
    

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        backtracking(candidates,target,0,0);
        return res;
    }

    void backtracking(vector<int>& candidates,int target,int sum,int start){
        if(sum>target) return;
        if(sum==target){
            res.push_back(s);
            return;
        }

        for(int i=start;i<candidates.size();i++){//横向去重,纵向不去重
            sum+=candidates[i];
            s.push_back(candidates[i]);
            backtracking(candidates,target,sum,i);//这里不要加1了,表示当前数据可以重复加入
            sum-=candidates[i];
            s.pop_back();
            
        }
    }
};

リートコード40

候補の配列と目標数値ターゲットを指定して、数値の合計を目標にすることができる候補内のすべての組み合わせを見つけます。

候補内の各番号は、各組み合わせで 1 回のみ使用できます。

説明: すべての数値 (ターゲット数値を含む) は正の整数です。ソリューション セットには重複した組み合わせを含めることはできません。

  • 例 1:
  • 入力: 候補 = [10,1,2,7,6,1,5]、ターゲット = 8、
  • 解く集合は [
      [1, 7],
      [1, 2, 5],
      [2, 6],
      [1, 1, 6]
    ]です。
class Solution {
public:
    vector<vector<int>> res;
    vector<int> s;
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<int> used(candidates.size(),0);
        sort(candidates.begin(),candidates.end());//先排序,让相同的元素挨在一起
        backtracking(candidates, target,0,0,used);
        return res;
    }
    void backtracking(vector<int>& candidates, int target,int start,int sum,vector<int> &used){
        
        if(sum>target) return;
        if(sum==target){
            res.push_back(s);
            return;
        }
        
        for(int i=start;i<candidates.size();i++){//开树枝是用for循环,不断向下延伸是递归
            //if(i > 0 && candidates[i] == candidates[i-1] && used[i-1] == 0) continue;
            if(i > 0 && candidates[i] == candidates[i-1] && i>start) continue;
            //不使用used数组也可以,if(i > 0 && candidates[i] == candidates[i-1] && i>start) continue;
            //注意这里是判断used[i-1]
            sum+=candidates[i];
            s.push_back(candidates[i]);
            //used[i]=1;
            backtracking(candidates,target,i+1,sum,used);
            sum-=candidates[i];
            s.pop_back();
            //used[i]=0;
        }

    }
};

おすすめ

転載: blog.csdn.net/hbzdsXCV/article/details/130832642