力扣刷题总结—回溯篇

文章展示了几个使用回溯法解决组合问题的C++代码示例,包括组合、组合总和系列(I、II)以及电话号码的字母组合。这些算法用于找出给定条件下的所有可能组合,例如在一定范围内选择特定数量的数,或者将数字映射到字母生成所有可能的字符串组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 77.组合

class Solution {
private:
    vector<vector<int>> result; // 存放符合条件结果的集合
    vector<int> path; // 用来存放符合条件结果
    void backtracking(int n, int k, int startIndex) {
        if (path.size() == k) {
            result.push_back(path);
            return;
        }
        for (int i = startIndex; i <= n; i++) {
            path.push_back(i); // 处理节点
            backtracking(n, k, i + 1); // 递归
            path.pop_back(); // 回溯,撤销处理的节点
        }
    }
public:
    vector<vector<int>> combine(int n, int k) {
        result.clear(); // 可以不写
        path.clear();   // 可以不写
        backtracking(n, k, 1);
        return result;
    }
};

216.组合总和

class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    void traversal(int tarsum,int sum,int startindex,int k){
        if(sum>tarsum) return;//剪枝
        if(path.size()==k){
            if(tarsum==sum){
                result.push_back(path);
                return;
            }
        }
        //9-i+1>=k-path.size()
        //i<= 9 - (k - path.size()) + 1
        for(int i=startindex;i<=9;i++){
            sum+=i;
            path.push_back(i);
            traversal(tarsum,sum,i+1,k);
            sum-=i;
            path.pop_back();
        }

        return;
    }
    vector<vector<int>> combinationSum3(int k, int n) {
        path.clear();
        result.clear();
        traversal(n,0,1,k);
        return result;

    }
};

电话号码的组合

class Solution {
private:
    const string digitmap[10]={
        "",//0
        "",//1
        "abc",//2
        "def",//3
        "ghi",//4
        "jkl",//5
        "mno",//6
        "pqrs",//7
        "tuv",//8
        "wxyz"//9
    };
public:
    string s;
    vector<string> result;
    void traversal(string &digits,int k){
        if(k==digits.size()){
            result.push_back(s);
            return;
        }
        int digit = digits[k]-'0';
        string d = digitmap[digit];//完成数字到字母的映射
        for(int i=0;i<d.size();i++){
            s+=d[i];
            traversal(digits,k+1);
            s.pop_back();
        }
        return;
    }
    vector<string> letterCombinations(string digits) {
        s.clear();
        result.clear();
        if(digits=="") return result;
        traversal(digits,0);
        return result;

    }
};

组合总和I

class Solution {
public:
    vector<int> path;
    vector<vector<int>> result;
    void traversal(vector<int>& candidates, int target,int sum,int startindex){
        if(sum>target) return;
        if(sum==target){
            result.push_back(path);
            return;
        }
        for(int i=startindex;i<candidates.size();i++){
            path.push_back(candidates[i]);
            sum+=candidates[i];
            traversal(candidates,target,sum,i);
            path.pop_back();
            sum-=candidates[i];
        }
        return;
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        path.clear();
        result.clear();
        traversal(candidates,target,0,0);
        return result;
        
    }
};

组合总和II

class Solution {
public:
    vector<int> path;
    vector<vector<int>> res;
    void traversal(vector<int>& candidates,int target,int sum,int startindex,vector<bool>& used){
        if(sum>target) return;
        if(sum==target){
            res.push_back(path);
            return;
        }
        for(int i=startindex;i<candidates.size();i++){
            if(i>0&&candidates[i]==candidates[i-1]&&used[i-1]==false) continue;
            sum+=candidates[i];
            path.push_back(candidates[i]);
            used[i]=true;
            traversal(candidates,target,sum,i+1,used);
            sum-=candidates[i];
            path.pop_back();
            used[i]=false;
        }
        return;
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        path.clear();
        res.clear();
        vector<bool> used(candidates.size(),false);
        // 首先把给candidates排序,让其相同的元素都挨在一起。
        sort(candidates.begin(), candidates.end());
        traversal(candidates,target,0,0,used);
        return res;

    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值