[array] leetcode - 39. Combination Sum - Medium

leetcode - 39. Combination Sum - Medium

descrition

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]
]

解析

典型的回溯法求解。代码实现中给出了 3 中回溯的方式,都 accepted。微妙的区别应该是在递归的层数不同。对于 candidates[index] 只有两种情况,即:选择或不选择,值得注意的是如果选择的话可以多次重复选择。(可以使用状态转换图进行抽象更便于理解,重复选择实际上是在 index 状态有环,而不选择则是向 index + 1 状态的迁移)

注意:

  • 调用函数前用了一个排序,主要是为了递归时剪枝做准备,数组是递增排序,如果太大则可以停止更深层的递归
  • 题目说了所有数都是 positive,这其实也可以作为剪枝的条件
  • 题目说数组中不存在 duplicate 元素,如果存在的话还需要跳过重复的元素。

一般的,对于回溯问题,找好递归求解的子结构,记得结束点即出口的检查,避免无限循环。在递归过程中可以思考是否可以进行剪枝。

code


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Solution{
public:
    vector<vector<int> > combinationSum(vector<int>& candidates, int target){
        vector<vector<int> > ans;
        vector<int> vecCur;
        sort(candidates.begin(), candidates.end());

        combinationSumBacktracking0(candidates, 0, target, vecCur, ans);
        //combinationSumBacktracking1(candidates, 0, target, vecCur, ans);
        //combinationSumBacktracking2(candidates, 0, target, vecCur, ans);
        return ans;
    }

    // candidates in ascending
    void combinationSumBacktracking0(vector<int>& candidates, int index, int target,
                        vector<int>& vecCur, vector<vector<int> >& ans){
        if(target < 0)
            return;
        if(target == 0 && !vecCur.empty()){
            ans.push_back(vecCur);
            return;
        }
        // sub-problem, for each element in candidates[index,...,n-1]
        // just have two condition: choose or not
        for(int i=index; i<candidates.size(); i++){
            if(candidates[i] > target) // Note: candidates must in ascending order
                break;
            // note: not i+1, because the same repeaded number may be chosen from candidates
            vecCur.push_back(candidates[i]);
            combinationSumBacktracking0(candidates, i, target - candidates[i], vecCur, ans);
            vecCur.pop_back();
        }
    }

    void combinationSumBacktracking1(vector<int>& candidates, int index, int target,
                                    vector<int>& vecCur, vector<vector<int> >& ans){
        if(target < 0)
            return;
        if(target == 0){
            if(!vecCur.empty())
                ans.push_back(vecCur);
            return;
        }
        if(index >= candidates.size())
            return;

        // choose candidates[index]
        // Note: candidates[index] can be choose more than onece
        vecCur.push_back(candidates[index]);
        combinationSumBacktracking1(candidates, index, target - candidates[index], vecCur, ans);
        vecCur.pop_back();

        // dosen‘t choose candidates[index]
        combinationSumBacktracking1(candidates, index+1, target, vecCur, ans);
    }

    void combinationSumBacktracking2(vector<int>& candidates, int index, int target,
                                     vector<int>& vecCur, vector<vector<int> >& ans){
        if(target < 0)
            return;
        if(target == 0){
            if(!vecCur.empty())
                ans.push_back(vecCur);
            return;
        }
        if(index >= candidates.size())
            return;

        // choose candidates[index] more than times
        int i = 1;
        for(; i*candidates[index] <= target; i++){
            vecCur.push_back(candidates[index]);
            combinationSumBacktracking2(candidates, index+1, target - i*candidates[index], vecCur, ans);
        }
        for(int j=i-1; j>=1; j--)
            vecCur.pop_back();

        // don‘t choose candidates[index]
        combinationSumBacktracking2(candidates, index+1, target, vecCur, ans);
    }
};

int main()
{
    return 0;
}
时间: 2024-10-13 02:00:30

[array] leetcode - 39. Combination Sum - Medium的相关文章

[array] leetcode - 40. Combination Sum II - Medium

leetcode - 40. Combination Sum II - Medium descrition Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. Each number in C may only be used once in the combinat

[LeetCode] 039. Combination Sum (Medium) (C++)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 039. Combination Sum (Medium) 链接: 题目:https://leetcode.com/problems/combination-sum/ 代码(github):https://github.com/illuz/leetcode 题意: 给出一些正整数集合,以及一个目标数,从集合中选择一

leetCode 39.Combination Sum(组合总和) 解题思路和方法

Combination Sum Given a set of candidate numbers (C) 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 (includi

LeetCode 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 (in

Java [Leetcode 39]Combination Sum

题目描述: Given a set of candidate numbers (C) 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)

LeetCode 39 Combination Sum(满足求和等于target的所有组合)

题目链接: https://leetcode.com/problems/combination-sum/?tab=Description Problem: 给定数组并且给定一个target,求出所有满足求和等于target的数字组合 遍历所有的数组中元素,然后对target进行更新,将该元素添加到tempList中,直到remain等于0时达到条件,可以将该tempList添加到list中 注意:每个元素可以使用多次,因此每次的遍历都要从上次的那个下标开始. 当target更新到小于0的时候,返

19.2.3 [LeetCode 39] Combination Sum

Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. The same repeated number may be chosen from candidates unlimited n

[leetcode] 040. Combination Sum II (Medium) (C++)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 040. Combination Sum II (Medium) 链接: 题目:https://leetcode.com/problems/combination-sum-ii/ 代码(github):https://github.com/illuz/leetcode 题意: 跟 039 一样(给出一些正整数集合,

Java for LeetCode 216 Combination Sum III

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. Ensure that numbers within the set are sorted in ascending order. Example 1