【Leetcode每日一题】 综合练习 - 电话号码的字母组合(难度⭐⭐)(75)

1. 题目解析

题目链接:电话号码的字母组合

这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。

2.算法原理

算法设计思路

在解决这类问题时,我们需要认识到每个位置上的数字对应的字符集合是相互独立的,即一个位置上的字符选择不会影响到其他位置上的字符选择。基于这一观察,我们可以采用回溯法来构建所有可能的字符组合。

关键数据结构

首先,我们需要一个字典(在C++中可以使用unordered_map)来存储每个数字对应的字符集合。这个字典我们称之为phoneMap,其中键是数字(字符型),值是该数字对应的所有可能字符组成的字符串。

递归函数设计

接下来,我们定义一个递归函数backtrack来构建所有可能的字符组合。该函数需要接受三个参数:

  1. phoneMap:数字到字符集合的映射字典。
  2. digits:输入的电话号码字符串,其中包含的数字需要被转换为字符组合。
  3. index:当前正在处理的数字在digits中的索引。

函数内部不需要额外的返回值(可以使用void),但需要一些额外的数据结构来保存中间状态和最终结果。这里我们使用一个字符串ans来保存当前的字符组合状态,以及一个容器(比如vector<string>)来保存所有有效的字符组合结果。

递归流程

  1. 递归结束条件:当index等于digits的长度时,说明我们已经处理了所有的数字,此时ans中保存的就是一个有效的字符组合。我们将ans加入到结果容器中,并返回上一层递归。

  2. 处理当前数字:从digits中取出当前索引index对应的数字digit,然后根据phoneMap找到对应的字符集合letters

  3. 遍历字符集合:对于letters中的每一个字符letter,我们执行以下操作:

    • letter添加到当前的字符组合ans的末尾。
    • 递归调用backtrack函数,传入index + 1作为下一个要处理的数字的索引。
    • 在递归调用返回后,我们需要将刚刚添加到ans末尾的letter删除,以进行回溯,尝试其他可能的字符。
  4. 返回结果:当所有的递归调用都完成后,我们的结果容器中就已经保存了所有可能的字符组合。最后,我们返回这个结果容器即可。

tips:

  • 在递归过程中,我们需要确保每次递归调用都是基于当前状态的独立副本,以避免修改原始数据或产生意外的副作用。
  • 由于递归的深度可能很大(特别是当输入的电话号码很长时),我们需要确保递归的实现是高效且没有栈溢出的风险的。在某些情况下,可能需要考虑使用迭代或显式的栈结构来替代递归。
  • 为了代码的可读性和可维护性,我们应该尽量将逻辑拆分成小的、可重用的函数或方法,并添加适当的注释和文档。

3.代码编写

class Solution {
    string hash[10] = {"",    "",    "abc",  "def", "ghi",
                       "jkl", "mno", "pqrs", "tuv", "wxyz"};
    string path;
    vector<string> ret;

public:
    vector<string> letterCombinations(string digits) {
        if(digits.size() == 0) return ret;
        dfs(digits, 0);
        return ret;
    }
    void dfs(string& digits, int pos)
    {
        if(pos == digits.size())
        {
            ret.push_back(path);
            return;
        }
        for(auto& ch : hash[digits[pos] - '0'])
        {
            path.push_back(ch);
            dfs(digits, pos + 1);
            path.pop_back();
        }
    }
};

The Last

嗯,就是这样啦,文章到这里就结束啦,真心感谢你花时间来读。

觉得有点收获的话,不妨给我点个吧!

如果发现文章有啥漏洞或错误的地方,欢迎私信我或者在评论里提醒一声~

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

每天进步亿丢丢

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

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

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

打赏作者

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

抵扣说明:

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

余额充值