leetcode 17电话号码的字母组合

可以,这道"电话号码的字母组合"就按你刚才喜欢的那种方式总结。

复制代码
class Solution {
public:
    vector<string> res;  // 保存所有字母组合

    vector<string> letternumber = {
        "", "", "abc", "def", "ghi",
        "jkl", "mno", "pqrs", "tuv", "wxyz"
    };

    vector<string> letterCombinations(string digits) {
        string tmp;  // 当前正在构造的字符串

        backtracing(0, digits, tmp);

        return res;
    }

    void backtracing(int pos, string digits, string& tmp) {

        // 所有数字都已经处理完,得到一个完整组合
        if (pos == digits.length()) {
            res.push_back(tmp);
            return;
        }

        // 取出当前数字
        int num = digits[pos] - '0';

        // 遍历当前数字对应的所有字母
        for (int i = 0; i < letternumber[num].size(); i++) {

            // 做选择
            tmp.push_back(letternumber[num][i]);

            // 进入下一层,处理下一个数字
            backtracing(pos + 1, digits, tmp);

            // 回溯:撤销刚才选择的字母
            tmp.pop_back();
        }
    }
};

这题可以按照你刚才说的"回溯参数五件套"来分析。

复制代码
原始数据:digits
当前路径:tmp
当前位置:pos
额外状态:不需要
结果集:res

所以回溯函数就是:

复制代码
void backtracing(int pos, string digits, string& tmp)

其中最重要的三个东西:

复制代码
pos

表示当前正在处理:

复制代码
digits[pos]

例如:

复制代码
digits = "23"

pos = 0 → 处理数字 2
pos = 1 → 处理数字 3
pos = 2 → 全部处理完成

复制代码
tmp

表示当前已经选择出来的字母组合。

例如:

复制代码
""
"a"
"ad"

每次:

复制代码
tmp.push_back(...)

就是选择当前数字对应的一个字母。

每次:

复制代码
tmp.pop_back()

就是撤销选择。


复制代码
letternumber

负责建立:

复制代码
数字 → 字母

的映射。

例如:

复制代码
2 → abc
3 → def
7 → pqrs
9 → wxyz

所以:

复制代码
int num = digits[pos] - '0';

先把字符 '2' 转成整数 2。

然后:

复制代码
letternumber[num]

就可以得到:

复制代码
"abc"

这题最核心的三步依然是:

复制代码
tmp.push_back(letternumber[num][i]);  // 做选择

backtracing(pos + 1, digits, tmp);    // 进入下一层

tmp.pop_back();                       // 撤销选择

也就是:

做选择 → 递归下一层 → 撤销选择

比如:

复制代码
digits = "23"

递归过程:

复制代码
                 ""
              处理数字2
          /       |       \
         a        b        c
       处理3    处理3    处理3
      / | \      ...      ...
     d  e  f

得到:
ad
ae
af
bd
be
bf
cd
ce
cf

这道题和你前面做过的题还有一个很重要的区别:

全排列是:

每一层从"所有没有使用过的数字"中选择。

所以需要:

复制代码
used

子集是:

每一层从 index 后面的数字中选择。

所以需要:

复制代码
index

而电话号码组合是:

第 pos 层只能处理 digits[pos] 对应的字母。

所以这里需要的是:

复制代码
pos

一句话总结这道题:

每一层递归处理一个数字,从该数字对应的字母中选择一个加入 tmp,然后 pos+1 处理下一个数字,递归回来后撤销当前选择。

你以后看到这种"每个位置都有若干种选择,要求组合出所有结果"的题,就可以优先想到这种回溯结构。

相关推荐
zyl76514 小时前
FlashAttention 详解:从 GPU 硬件、普通 Attention 到分块计算与 Online Softmax
算法
爱读书的小胖18 小时前
LeetCode 122:买卖股票的最佳时机 II(C)解题分析
算法
结局无敌18 小时前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
ychqsq18 小时前
234.无题
经验分享·职场和发展
OPEN-F18 小时前
ROS2系列教程:上位机建图与导航(原理综合)
算法·机器人
weixin_3077791318 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
tomwang032218 小时前
路径优化建模、优化算法分类及工程化小结
算法·数学建模·分类
小羊没烦恼!18 小时前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp
考研保研资料分享19 小时前
物理保研至中科大:固体物理复习、四场面试与科研追问
面试·职场和发展
2501_9269783319 小时前
人机通信协议--人和机器之间的交互想象
人工智能·经验分享·算法·ai写作