Combinatorial sum problem, leetcode77, 216, 39, 40

 leetcode77

Given two integers  n and  sum k, return  [1, n] all possible  k combinations of numbers in the range. You can return answers in  any order  .

Input: n = 4, k = 2
 Output:
[
  [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();//回溯
    }
    }
};

 

leetcode 216

Find all combinations of k numbers that add up to n. Only positive integers from 1 to 9 are allowed in the combination, and there are no repeated numbers in each combination.

illustrate:

  • All numbers are positive integers.
  • A solution set cannot contain duplicate combinations.

Example 1: Input: k = 3, n = 7 Output: [[1,2,4]]

Example 2: Input: k = 3, n = 9 Output: [[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;
        }
    }
};

 leetcode 39

Given an array candidates without repeated elements and a target number target, find out all combinations in candidates that can make the sum of numbers into target.

The numbers in candidates can be selected repeatedly without limit.

illustrate:

  • All numbers (including target) are positive integers.
  • A solution set cannot contain duplicate combinations.
  • Example input: candidates = [2,3,6,7], target = 7,
  • The solved set is: [ [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();
            
        }
    }
};

leetcode 40

Given an array of candidates and a target number target, find all the combinations in candidates that can make the sum of numbers into target.

Each number in candidates can only be used once in each combination.

Explanation: All numbers (including the target number) are positive integers. A solution set cannot contain duplicate combinations.

  • Example 1:
  • Input: candidates = [10,1,2,7,6,1,5], target = 8,
  • The set to be solved is: [
      [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;
        }

    }
};

Guess you like

Origin blog.csdn.net/hbzdsXCV/article/details/130832642