【每日刷题】组合总和

题目地址

https://leetcode-cn.com/problems/combination-sum/

题目描述:组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。

示例:

例 1:

输入: candidates = [2,3,6,7], target = 7,

所求解集为:[ [7], [2,2,3] ]

例 2:

输入: candidates = [2,3,5], target = 8,

所求解集为:

[[2,2,2,2], [2,3,3], [3,5]]

解答

该题有两种方法。

方法一:dfs + 回溯

对于每一个元素,存有两种状态:选中、没有选中。(可以重复选择)。

依据上述原理,对原数组进行深搜。

何时终止呢?

当目前选中的元素和大于/等于 target 值时,即可终止。

代码:

class Solution {
public:
    vector<vector<int>> res;
    
    void dfs( vector<int>& candidates, int target, int begin, vector<int> temp){
        if( !target){
            res.push_back( temp);
            return ;
        }
        
        for( int i = begin; i < candidates.size(); i++){
            if( target - candidates[i] >= 0){
                temp.push_back( candidates[i]);
                //每个元素都可以用无数次,因此从当前元素开始
                dfs( candidates, target -candidates[i], i, temp);
                temp.pop_back();
            }
            else
                break;
        }
    }
    
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        //排序预处理
        sort( candidates.begin(), candidates.end());
        
        dfs( candidates, target, 0, {});
        
        return res;
    }
};

方法二:动态规划

当 target 较小时,dp 适用于该题。但若 target 太大,则不再适用。

这里先略过 dp 的解法,等到后面相似题目再讲解。

你可能感兴趣的:(每日刷题)