代码随想录算法训练营第二十五天| 216.组合总和III、17.电话号码的字母组合

组合总和III

题目链接:力扣
这道题和昨天那道组合题的思路是一致的,代码也非常相似。本题k相当于树的深度,9(因为整个集合就是9个数)就是树的宽度。

为了方便理解,我还是 套用了上一题的套路,将路径总和sum的计算放在终止条件中进行判断。当path的数目=k时,比较此时sum和目标值n是否相等。

class Solution {
public:
    vector<vector<int>> combinationSum3(int k, int n) {

        backtracking(k,n,1);
        return result;
    }

    vector<vector<int>> result;
    vector<int> path;

    void backtracking(int k,int n, int startIndex)
    {
        if(path.size() == k)
        {
            int sum =0;
            for(int i=0;i<k;i++)
                sum += path[i];
            if(sum == n)
            result.push_back(path);
            return;
        }

        for(int i= startIndex; i<=9 ;i++)
        {
            path.push_back(i);
            backtracking(k,n,i+1);
            path.pop_back();
        }
    }
};

当然 也可以将sum的计算放在回溯的过程中,这样的话backtracking中就要带4个参数:

  void backtracking(int n, int k, int sum, int startIndex)

那么for循环中的内容将改为:sum和path要跟着回溯的过程进行变化!

  for (int i = startIndex; i <= 9; i++) {
            sum += i; // 处理
            path.push_back(i); // 处理
            backtracking(n, k, sum, i + 1); // 注意i+1调整startIndex
            sum -= i; // 回溯
            path.pop_back(); // 回溯
        }

 电话号码的字母组合

题目链接:力扣

这题感觉很有意思, 一开始做的时候,没有理清楚思路,急于把输入的数字先全部变成字母了,然后后面就遇到了困难。写不下去。
其实呢,输入的字符长度(例如“23”)就代表着遍历的深度,而遍历的长度就是单个数字对应字符串的长度。

这样想就容易很多:
 

class Solution {
public:
    vector<string> res;
    string path;
    vector<string> letterCombinations(string digits) {
        if(digits == "") return res;

         backtracking(digits, 0);
         return res; 

    }
     void backtracking(const string& digits, int index)    //index为记录遍历第几个数字,同时也表示树的深度
     {                                                      //递归实现深度 for循环实现宽度
         if(path.size() == digits.size())
         {
            res.push_back(path);
            return;
         }

         int num = digits[index] - '0';             // 将index指向的数字转为int
         string letters = corresponding(num);       // 取数字对应的字符集
         for (int i = 0; i < letters.size(); i++) {
                path.push_back(letters[i]);         // 处理
                backtracking(digits, index + 1);    // 递归,注意index+1,一下层要处理下一个数字了
                path.pop_back();                       // 回溯
             }
     }

    string corresponding(int num)
    {
        switch(num)
        {
            case 2: return "abc";
            case 3: return "def";
            case 4: return "ghi";
            case 5: return "jkl";
            case 6: return "mno";
            case 7: return "pqrs";
            case 8: return "tuv";
            case 9: return "wxyz";
            default: return "";
        }       
    }

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值