深搜练习(电话号码字母组合)(3)

一.题目

17. 电话号码的字母组合 - 力扣(LeetCode)

二.思路讲解

2.1 思路讲解

本题要求将输入的数字字符串(仅含 2-9)映射成对应的字母组合,本质是一个多阶段决策 问题。我们需要先建立数字到字母的映射表,例如用数组 string mapping[10] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};,这样下标 2 对应 "abc",3 对应 "def",以此类推。

以 digits = "23" 为例,决策树的每一层对应一个数字,每个数字对应多个字母分支。从根开始,第一层选择 'a'、'b'、'c' 之一,第二层再为第二个数字选择对应的字母,这样就能得到所有组合。当遍历到叶子节点 (即已处理完所有数字)时,当前路径 path 就是一个完整的字母组合,将其加入结果集 ret 中。

实现思路:

  • 使用深度优先搜索(DFS) ,递归函数 dfs(pos) 表示当前处理到第 pos 个数字(从 0 开始)。

  • 当 pos == digits.size() 时,将 path 加入结果并返回。

  • 否则,获取当前数字对应的字母串,依次遍历每个字母,将其加入 path,递归下一层,然后回溯(弹出最后一个字母)。

三.代码演示

cpp 复制代码
class Solution 
{
public:
    string str[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    string path;
    vector<string>ret;
    vector<string> letterCombinations(string digits) 
    {
        if(digits.size() == 0)
            return {""};
        dfs(digits,0);
        return ret;
    }
    void dfs(string digits,int pos)
    {
        if(pos == digits.size())
        {
            ret.push_back(path);
            return;
        }
        for(auto ch : str[digits[pos] - '0'])
        {
            path.push_back(ch);
            dfs(digits,pos+1);
            path.pop_back();
        }
    }

};

四.代码讲解

一、映射表与全局变量

首先,我们需要建立数字到字母的映射关系。使用一个字符串数组 str ,长度为 10,下标 0 和 1 留空,下标 2~9 分别对应电话按键上的字母串。例如 str[2] = "abc",str[3] = "def",以此类推。同时,定义两个成员变量:

  • path:字符串,记录当前正在构建的字母组合。

  • ret:字符串数组,存储所有生成的完整字母组合。

二、主函数 letterCombinations

主函数接收输入的数字字符串 digits。根据题目提示,digits.length 至少为 1,但为了鲁棒性,代码中先判断 digits.size() == 0 时直接返回包含空字符串的向量 {""}。这对应空输入的情况。然后调用递归函数 dfs(digits, 0),从第一个数字开始深度优先搜索,最后返回结果集 ret。

三、递归函数 dfs

递归函数 dfs(digits, pos) 的含义是:当前已经处理了前 pos 个数字(即 path 中已有 pos 个字母),接下来需要处理第 pos 个数字(下标从 0 开始)。执行流程如下:

1. 递归终止条件

当 pos == digits.size() 时,说明已经处理完了所有数字,当前 path 就是一个完整的字母组合,将其加入 ret,然后返回。

2. 获取当前数字对应的字母串

通过 digits[pos] - '0' 得到当前数字(字符转整数),然后从映射表 str 中取出对应的字母字符串 s。

3. 遍历字母串并递归

使用范围 for 循环遍历 s 中的每一个字符 ch:

  • 将 ch 追加到 path 末尾(path.push_back(ch))。

  • 递归调用 dfs(digits, pos+1),处理下一个数字。

  • 递归返回后,恢复现场 :将 path 末尾的字符弹出(path.pop_back()),以便尝试当前数字的下一个字母。

四、回溯与恢复现场

由于 path 是全局变量,每次递归后必须手动恢复现场,即弹出刚刚加入的字母。

相关推荐
青少儿编程课堂25 分钟前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会Scratch考级:校园连连看解析
c++·python·算法·bfs·信息学竞赛
kongdong36 分钟前
Hikyuu | RSI均值回归交易策略实现
算法·均值算法·回归·量化交易·交易策略·hikyuu
小王C语言1 小时前
优选算法:分治-归并排序
算法
草莓熊Lotso1 小时前
【C++ 基于微服务的即时通讯系统】文件存储子服务实战:UUID生成、文件IO封装与全接口单元测试
开发语言·网络·数据库·c++·微服务·架构·单元测试
非优秀程序员11 小时前
第05章 播放器大战,暴风、快播与那一夜|《互联网产品恩仇录》
算法
武子康18 小时前
驾驶轨迹换个坐标,就能给移动机器人用吗?
人工智能·算法·机器学习
David猪大卫18 小时前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
HPtiger18 小时前
C++ 入门笔记:从 C 到 C++ 的核心过渡(命名空间、输入输出、缺省参数、重载、引用、内联)
c语言·c++·学习
努力努力再努力wz21 小时前
【Lua 进阶系列】从 C++ 对象到 Lua 变量:一文理解 userdata、Lua 栈与元表绑定机制
c++·junit·lua