回溯算法

39.组合

搜索、回溯问题的套路是画图,代码是根据树形图写出来的。

回溯算法_第1张图片

class Solution {
public:
    void backtracking(vector>& res,vector& candidates,vectorsubset,int target,int start){
        //1.candidates数据需要排序 升序会比较快
        //2.深层数字需要不大于浅层数字,即i>=start
        if(target==0){
            res.push_back(subset);
            return;
        }
        if(targettarget){
                break;
            }
            subset.push_back(candidates[i]);
            backtracking(res,candidates,subset,target-candidates[i],i);
            subset.pop_back();
        }
        return;
    }
    vector> combinationSum(vector& candidates, int target) {
        vector>res;
        vectorsubset;
        sort(candidates.begin(),candidates.end());
        backtracking(res,candidates,subset,target,0);
        return res;
    }
};

78.子集

基本思想:在每个子集中,nums中的每个元素都有“出现”和“不出现”两种可能,因此每个子集都可以表示为一棵二叉树中根节点到叶节点的路径。

回溯算法_第2张图片

方法一:DFS:搜索所有的从根节点到叶节点的路径即可得到所有子集。

方法二:回溯:搜索解空间并进行剪枝。

回溯算法_第3张图片

class Solution {
public:
    //1.dfs
    void dfs(vector>& res,vector& nums,vector& subset,int level){
        if(level==nums.size()){
            res.push_back(subset);
            return;
        }
        subset.push_back(nums[level]);
        dfs(res,nums,subset,level+1);
        subset.pop_back();
        dfs(res,nums,subset,level+1);
        return;
    }
    //2.回溯
    void backtracking(vector>& res,vector& nums,vector& subset,int level){
        if(level<=nums.size()){
            res.push_back(subset);
        }
        for(int i=level;i> subsets(vector& nums) {
        vector>res;
        vectorsubset;
        //dfs(res,nums,subset,0);
        backtracking(res,nums,subset,0);
        return res;
    }
};

 

你可能感兴趣的:(数据结构与算法)