代码随想录训练营第25天|LeetCode 216.组合总和III、17.电话号码的字母组合

参考

代码随想录

题目一:LeetCode 216.组合总和III

会了昨天组合之后,这题就很简单了,除了用一个path保存路径外,再使用一个变量sum来保存路径的和。

  1. 确定递归函数的参数和返回值
    参数:n,k,以及每次遍历的起始位置start.
    返回值:无
void backtracking(int k,int n,int start);
  1. 确定递归终止条件:当path中元素个数等于k时,若路径值之和等于n,就将path保存到result中,然后结束递归
if(path.size() == k){
	if(sum == n) result.push_back(path);
    return;
}
  1. 确定单层搜索过程:for循环遍历树型结构的宽度,递归调用遍历深度,每次递归结束后进行回溯
for (int i = start; i <= 9; i++){
    sum += i;
    path.push_back(i);
    backtracking(k,n,i+1);
    sum -= i;           //回溯
    path.pop_back();   
}

完整的代码实现如下:

class Solution {
public:
    void backtracking(int k,int n,int start)
    {
        if(path.size() == k){
            if(sum == n) result.push_back(path);
            return;
        }
        
        for (int i = start; i <= 9; i++){
            sum += i;
            path.push_back(i);
            backtracking(k,n,i+1);
            sum -= i;           //回溯
            path.pop_back();   
        }
    }
    vector<vector<int>> combinationSum3(int k, int n) {
        backtracking(k,n,1);
        return result;
    }
private:
    vector<int> path;
    int sum = 0;
    vector<vector<int>> result;
};

剪枝

第一个地方和昨天的组合一样,对for循环的条件进行修改,当剩余元素不足所需要的元素个数时结束遍历,如下:

for (int i = start; i <= 10 - k + path.size(); i++){
	......
}

第二个是当sum > n时直接退出:

if(sum > n) return;

剪枝后完整的代码如下:

class Solution {
public:
    void backtracking(int k,int n,int start)
    {
        if(sum > n) return;
        if(path.size() == k){
            if(sum == n) result.push_back(path);
            return;
        }
        
        for (int i = start; i <= 10 - k + path.size(); i++){
            sum += i;
            path.push_back(i);
            backtracking(k,n,i+1);
            sum -= i;           //回溯
            path.pop_back();   
        }
    }
    vector<vector<int>> combinationSum3(int k, int n) {
        backtracking(k,n,1);
        return result;
    }
private:
    vector<int> path;
    int sum = 0;
    vector<vector<int>> result;
};

题目二:LeetCode 17.电话号码的字母组合

字母和数字的映射

用一个string类型的数组来进行映射,如下:

string trans[8] = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

如果数字字符为ch,则其对应的字符串为trans[ch-‘2’],因为上面的数组中没有’0’和’1’对应的字符串,所以要减去偏移,当然也可以把’0’和’1’对应的字符串设置为空。

递归+for循环

用for循环来遍历每个数字对应的字符串,用递归来遍历每个数字。

  1. 确定递归函数的参数和返回值
    参数:数字字符串digits,遍历每个数字字符的指针index
    返回值:无
void backtracking(string digits,int index);

用path来保存遍历路径,result来保存最终的结果。

string path;
vector<string> result;
  1. 确定终止条件:当path保存的元素个数等于数字字符串的大小时,找到一个满足条件的答案,保存这个结果,然后结束本次递归。
if(path.size() == digits.size()){
 result.push_back(path);
    return;
}
  1. 确定单层搜索逻辑:用for循环来遍历每个字符对应的字母,用递归来遍历那个数字
string str = trans[digits[index]-'2'];  //得到index指向的数字对应的字符
for(int i = 0;i < str.size(); i++){ //for循环遍历每个数字对应的字符
    path += str[i]; //保存遍历结果
    backtracking(digits,index+1); //递归遍历每个数字
    path.erase(path.end()-1);   //回溯
}

完整的代码实现如下:

class Solution {
public:
    void backtracking(string digits,int index) //index遍历每个数字
    {
        if(path.size() == digits.size()){
            result.push_back(path);
            return;
        }
        string str = trans[digits[index]-'2'];  //得到index指向的数字对应的字符
        for(int i = 0;i < str.size(); i++){ //for循环遍历每个数字对应的字符
            path += str[i]; //保存遍历结果
            backtracking(digits,index+1); //递归遍历每个数字
            path.erase(path.end()-1);   //回溯
        }
    }
    vector<string> letterCombinations(string digits) {
        if(digits == "")    return {};
        backtracking(digits,0);
        return result;
    }
private:
    string path;
    vector<string> result;
    string trans[8] = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忆昔z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值