欢迎来到李耶的频道【LeetCode面试题】。
电话号码的字母组合
题目
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
2: "abc"
3: "def"
4: "ghi"
5: "jkl"
6: "mno"
7: "pqrs"
8: "tuv"
9: "wxyz"
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
输入:digits = ""
输出:[]
输入:digits = "2"
输出:["a","b","c"]
解法一:回溯法(DFS)
思路:使用深度优先搜索(DFS)遍历所有可能的组合。维护一个路径字符串,每次递归选择一个数字对应的一个字母,直到处理完所有数字。
javascript
function letterCombinations(digits) {
if (!digits || digits.length === 0) return [];
const map = {
'2': 'abc',
'3': 'def',
'4': 'ghi',
'5': 'jkl',
'6': 'mno',
'7': 'pqrs',
'8': 'tuv',
'9': 'wxyz'
};
const result = [];
function backtrack(index, path) {
if (index === digits.length) {
result.push(path);
return;
}
const letters = map[digits[index]];
for (const letter of letters) {
backtrack(index + 1, path + letter);
}
}
backtrack(0, '');
return result;
}
- 时间复杂度 / 空间复杂度:O(3^m × 4^n) / O(m + n),其中 m 是 3 个字母的数字个数,n 是 4 个字母的数字个数
- 优势:经典回溯模板,逻辑清晰,是面试中最推荐的写法
解法二:队列法(BFS)
思路:使用队列进行广度优先搜索(BFS)。初始队列为空字符串,逐个处理每个数字,对于队列中每个已有组合,扩展当前数字对应的所有字母。
javascript
function letterCombinations(digits) {
if (!digits || digits.length === 0) return [];
const map = {
'2': 'abc',
'3': 'def',
'4': 'ghi',
'5': 'jkl',
'6': 'mno',
'7': 'pqrs',
'8': 'tuv',
'9': 'wxyz'
};
let queue = [''];
for (const digit of digits) {
const letters = map[digit];
const newQueue = [];
for (const prefix of queue) {
for (const letter of letters) {
newQueue.push(prefix + letter);
}
}
queue = newQueue;
}
return queue;
}
- 时间复杂度 / 空间复杂度:O(3^m × 4^n) / O(3^m × 4^n)
- 优势:BFS 思路,适合理解不同的遍历方式
- 劣势:需要存储中间结果,空间占用略大
解法三:迭代法(循环拼接)
思路:使用循环逐个数字处理,每次用当前结果集与当前数字对应的字母列表进行笛卡尔积拼接,生成新的结果集。
javascript
function letterCombinations(digits) {
if (!digits || digits.length === 0) return [];
const map = {
'2': 'abc',
'3': 'def',
'4': 'ghi',
'5': 'jkl',
'6': 'mno',
'7': 'pqrs',
'8': 'tuv',
'9': 'wxyz'
};
let result = [''];
for (const digit of digits) {
const letters = map[digit];
const newResult = [];
for (const prefix of result) {
for (const letter of letters) {
newResult.push(prefix + letter);
}
}
result = newResult;
}
return result;
}
- 时间复杂度 / 空间复杂度:O(3^m × 4^n) / O(3^m × 4^n)
- 优势:代码简洁,与 BFS 本质相同
- 劣势:与 BFS 类似,空间占用略大
解法对比
| 解法 | 时间 / 空间复杂度 | 优势 | 推荐指数 |
|---|---|---|---|
| 回溯法(DFS) | O(3^m × 4^n) / O(m + n) | 递归经典,空间最优 | ⭐⭐⭐⭐⭐ |
| 队列法(BFS) | O(3^m × 4^n) / O(3^m × 4^n) | BFS 思路,易于理解 | ⭐⭐⭐⭐ |
| 迭代法 | O(3^m × 4^n) / O(3^m × 4^n) | 代码简洁,无需递归 | ⭐⭐⭐⭐ |
扩展题
- 括号生成 :给定
n对括号,生成所有由n对括号组成的有效组合。 - 组合总和:给定一个无重复元素的数组和一个目标数,找出所有可以使数字和等于目标数的组合。
- 子集:给定一个整数数组,返回该数组所有可能的子集(幂集)。
"他山之石,可以攻玉。" ------ 《诗经·小雅·鹤鸣》
关注李耶,每天一道面试题,一起卷起来 🔥