leetcode hot100#39. 组合总和(简单DFS) c++

题目

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

说明:

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

输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[ [7] , [2,2,3] ]

输入:candidates = [2,3,5], target = 8,
所求解集为:
[ [2,2,2,2] , [2,3,3] , [3,5] ]

提示:
1 <= candidates.length <= 30
1 <= candidates[i] <= 200
candidate 中的每个元素都是独一无二的。
1 <= target <= 500

题解:

简单dfs + 根据题意灵活改变搜索方案

搜索方案:

由于题目是独一元素,可以使用无数次,且方案要不重复。可以先将数组排序,下一层的搜索可以使用当前元素,但不能使用当前元素之前的元素。所以bfs传参可以传入当前元素的下标,作为下一层搜索的起始元素的下标。以实现方案不重复(看代码关键句)

之后可以简单剪枝一下提高搜索效率
剪枝1)计算过程中sum大于target时,下面的结果sum必大于target,可以直接不搜

剪枝2)由于题目是独一元素,如果一个数位搜索起点都不能搜索到结果,那么比它还大的数肯定搜索不到结果,基于这个想法,我们可以对输入数组进行排序,以减少搜索的分支;排序是为了提高搜索速度,非必要;

c++代码:

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> temp;
    int sum=0;
    void dfs(int step,vector<int>& candidates,int& target){
        if(sum==target){
            ans.push_back(temp);
            return;
        }
        if(sum>target)return ;
        for(int i=step;i<candidates.size();i++){
            temp.push_back(candidates[i]);
            sum+=candidates[i];
            dfs(i,candidates,target);//传入i,关键语句
            sum-=candidates[i];
            temp.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        dfs(0,candidates,target);
        return ans;
    }
};

你可能感兴趣的:(leetcode)