LeetCode刷题记录----17.电话号码的字母组合(Medium)

2025/8/24

题目(Medium):


我的思路:

很显然这题也可以用递归的方式来进行处理。我们对按顺序处理每一个数字,把它对应的字符加入结果种,再去递归处理它的下一位数字能得到的字符结果。当达到了长度之后就会把它加入到结果集种,之后再回溯到上一个位置,移除之前加入的字符,并尝试这个数字对应的下一个字符。

大致的步骤如下:

①声明一个哈希表用来映射数字字符和它对应的字符串

②回溯函数的递归终止条件:当前结果长度和目标长度相等,就把当前结果加入结果集中

③回溯函数的处理:获取当前位置的对应的数字字符,把该数字字符对应的字母加入结果

④回溯函数的递归:递归处理结果的下一位

⑤回溯:回溯到当前位置之后,再选择该数字字符对应的之前没有加入到结果中的字母

⑥递归都结束之后返回结果集

具体代码如下:

class Solution {
private:
    vector<string> res;
    unordered_map<char, string> letterMap = {
        {'2', "abc"}, 
        {'3', "def"}, 
        {'4', "ghi"}, 
        {'5', "jkl"},
        {'6', "mno"},
        {'7', "pqrs"},
        {'8', "tuv"},
        {'9', "wxyz"}
    };

    void backTrack(string& digits, string& output, int curIndex){
        if(output.size() == digits.size()){
            res.emplace_back(output);
            return;
        }

        //对每个数字字符进行处理
        char c1 = digits[curIndex];
        //对每个数字字符对应的字母进行处理
        for(const auto& c2 : letterMap[c1]){
            output += c2;

            backTrack(digits, output, curIndex + 1);

            output.pop_back();
        }
    }

public:
    vector<string> letterCombinations(string digits) {
        if(digits == "")
            return {};

        string output;
        backTrack(digits, output, 0);

        return res;
    }
};

时间复杂度:O(3^m×4^n)【m是对应3个字母的数字个数,n是对应4个字母的数字个数,需要遍历所有的组合可能性】

空间复杂度:O(m+n)【递归调用层的最大深度为m+n】


总结:

①对于这种需要遍历每一种组合的题目,用回溯的思想去做是最简单直观的

②对于这种每个元素有顺序限制的题目(比如这里“23”和“32”对应的答案不同且唯一),我们在递归的时候也按顺序递归来进行处理。对于不需要按顺序的题目(比如全排列[321]和[123]都是答案的一部分)我们就需要每次递归的时候都注意对每个数再进行从头遍历处理(当然这个也可以把他优化成按某种规定的顺序的,比如之前全排列中规定first指针左侧是已经排列好的,右侧是未排列的,这样也相当于让他有一定的顺序限制了)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

萘柰奈

谢谢老板喵

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

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

打赏作者

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

抵扣说明:

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

余额充值