代码随想录刷题第25天

第一题是组合总和,求满足大小为k,和为n的所有组合,根据回溯三部曲,确定以下参数:目标和targetsum,已有和sum,目标大小k,递归下标startsum。当组合大小==k,sum==targetsum时,将该组合放入结果集result中。注意回溯过程。

class Solution {
public:
vector path;
vector> result;
void travel(int targetsum,int sum,int k,int startindex){
    if(path.size()==k&&sum==targetsum) result.push_back(path);
    for(int i=startindex;i<=9;i++){
        path.push_back(i);
        sum+=i;
        travel(targetsum,sum,k,i+1);
        path.pop_back();
        sum-=i;
    }
}
    vector> combinationSum3(int k, int n) {
travel(n,0,k,1);
return result;
    }
};

不难注意到,当前代码中许多情况是可以避免的,当sum值过大时,后续元素的递归就不需要了,同时本题中对组合的大小有要求,当遍历到后续元素数量无法满足要求时,也可以直接跳出循环。剪枝后代码如下:

class Solution {
public:
vector path;
vector> result;
void travel(int targetsum,int sum,int k,int startindex){
    if(sum>targetsum) return;//对和进行剪枝
    if(path.size()==k&&sum==targetsum) result.push_back(path);
    for(int i=startindex;i<=9-(k-path.size())+1;i++){
        path.push_back(i);
        sum+=i;
        travel(targetsum,sum,k,i+1);//递归到满足终止条件
        path.pop_back();//回溯
        sum-=i;
    }
}
    vector> combinationSum3(int k, int n) {
travel(n,0,k,1);
return result;
    }
};

第二题是电话号码的字母组合,https://leetcode.cn/problems/letter-combinations-of-a-phone-number/与上题不同的是,本题是在不同集合中取值组合,因此在回溯中的传入参数会做一定的调整。​​​​​​​代码如下:

class Solution {
private:
const string letterMap[10] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz",};
public:
    vector result;
    string s;    
    void backtracking(const string& digits, int index){
        if(index == digits.size()) {result.push_back(s);return;}
        int digit = digits[index] - '0';
        string letters = letterMap[digit];
        for(int i = 0; i < letters.size(); i++){
            s.push_back(letters[i]);
            backtracking(digits, index + 1);//向后递归
            s.pop_back();
        }
    }
    vector letterCombinations(string digits) {
    s.clear();
    result.clear();
    if (digits.size() == 0) return result;
    backtracking(digits, 0);
    return result;
    }
};

通过这几题的解决,不难发现回溯法的代码形式较为固定,即终止条件——for循环遍历——递归——回溯。

你可能感兴趣的:(算法,leetcode,职场和发展)