跳到正文
第 17 题中等

电话号码的字母组合

Letter Combinations of a Phone Number

给定手机九宫格上的数字串,返回它能表示的所有字母组合。

在力扣中练习

题目描述

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

 

示例 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

示例 2:

输入:digits = "2"
输出:["a","b","c"]

 

提示:

  • 1 <= digits.length <= 4
  • digits[i] 是范围 ['2', '9'] 的一个数字。

解题思路

主解法

回溯 · 逐位选字母

每个数字选一个字母,选满 digits 长度就收集

组合的长度固定等于 digits 的长度,每一位从对应数字的字母集合里选一个。这正适合回溯:递归层数就是数字位置。

进入第 pos 位时,遍历它对应的所有字母;选一个、递归下一位、再撤销。到达 pos == digits.size() 时,path 就是一个完整组合。

分步图解

digits="24" 表示要取 2 个字母;空输入直接返回空结果。

数字串 · 每个数字取一个字母
0
1
2 → abc
4 → ghi
pos
res
[ ]
当前 path
空
1 / 4
第一个数字 2 取 a;第二个数字 4 依次取 g、h、i,得到 ag、ah、ai。

自拟输入 "24":2 对应 abc,4 对应 ghi,共 3×3=9 种。画面上 path 随选择增长,res 只在叶子收集。

分步图解

path "bg" 已经覆盖所有数字,复制进 res。

res.size
4
数字串 · 每个数字取一个字母
0
1
2 → abc
4 → ghi
pos
res
agahaibg
当前 path
b
g
1 / 4
回退到第一位换成 b,再完整枚举第二位;path 的撤销不会影响已保存的结果。

每个数字最多 4 个字母,时间 O(4ⁿ·n)(拼接结果占主导),递归深度 O(n)。空输入必须返回空结果,而不是包含空串的数组。

时间 O(4ⁿ·n)空间 O(n)

易错点

  • 空输入没有单独处理:会返回 [""],而题目要求 []。
  • 把 digits 的长度当成字母总长度:递归终止条件写错。
  • 忘记 path.pop_back():不同数字的字母会串在一起。
对照解法

迭代 · 逐位做笛卡尔积

从空串开始,每读一个数字就把结果集扩充一遍

空间峰值保存所有中间组合,最坏 O(4ⁿ);回溯版只占 O(n) 路径。

把结果看成一个不断扩大的集合:初始只有空串。每读一个数字,就把当前每个字符串分别接上该数字的每个字母,生成下一轮结果。

这是标准的笛卡尔积展开,代码没有递归,顺序也与回溯一致;代价是中间结果集可能非常大。

当结果数量本来就很大时,两者都无法避免输出规模;如果只要求第 k 个组合,回溯可以提前停止,迭代版则不适合。

  1. 1结果集初始化为 [""]。
  2. 2遍历每个数字。
  3. 3把每个已有字符串接上该数字的每个字母。
  4. 4用新结果集替换旧结果集。
时间 O(4ⁿ·n)空间 O(4ⁿ)

易错点

  • 空输入仍返回 [""]:需要提前返回空数组。
  • 在遍历 res 的同时修改 res:会不断读到刚生成的新串。

代码与演示

主解法配有图解;对照解法用于比较思路、复杂度或实现方式。

演示输入digits = "24"

digits="24" 表示要取 2 个字母;空输入直接返回空结果。

数字串 · 每个数字取一个字母
0
1
2 → abc
4 → ghi
pos
res
[ ]
当前 path
空
1 / 11
查看 C++ 代码

延伸阅读

  • 组合类回溯的终止条件通常是“位置走完”,而不是“和达到目标”;先明确这一点再写循环。
  • 如果数字包含 0 或 1,需要对空字母集做特殊处理,否则结果会变成空。