17. 电话号码的字母组合
文章目录
-
- [17. 电话号码的字母组合(https://leetcode.cn/problems/letter-combinations-of-a-phone-number/)](#17. 电话号码的字母组合)
- ==思路==
-
- [- 回溯法](#- 回溯法)
- 总结
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = "2"
输出:["a","b","c"]
思路
-
看到这种排列组合的题目第一时间就应该想到回溯法,想到回溯法不是最难的,难的是递归函数怎么写,下面我就带着大家一起思考一下
-
我们先来看一下这些字符是怎么拼接成字符串的
-
示例一(digits = "23"):
- 遍历到"2",先选"a",跳过"2"
- 遍历到"3",先选"d,跳过"3",发现"ad"的长度等于digits的长度,写入结果集
- 已经遍历到一个标准结果了,现在开始再原有基础上修改枚举
- 这个时候就要开始回溯了,删除"d",再选"e",发现"ae"的长度等于digits的长度,写入结果集
- 继续回溯,删除"e",写入"f",再写入结果集,数字"3"对应的字符遍历结束,再次回溯,删除最后一个字符"f"
- 继续回溯,到了数字"2",删除"a",写入"b",跳过"2",继续重复上面的操作
-
这个时候我们就发现了这么几个数据类型,一个是我们要记录我们遍历到哪一个数字了(可以用digits的下标锁定),第二个是回溯,当我们把第一个符合题目要求的字符串记录下来之后要开始回溯,逐个的倒着去枚举然后回溯,直到回溯到第一个字符全部枚举完为止,递归的讲解非常难以理解,下面用代码和图辅助理解一下吧
- 回溯法
go
func letterCombinations(digits string) []string {
//用哈希表记录对应关系
h := map[string]string{
"2" : "abc",
"3" : "def",
"4" : "ghi",
"5" : "jkl",
"6" : "mno",
"7" : "pqrs",
"8" : "tuv",
"9" : "wxyz",
}
//结果集,记录结果,返回结果
ret := []string{}
//记录已经添加的字符所形成的字符串
cur := []byte{}
//闭包,比较方便
var dfs func(index int)
dfs = func(index int) {
//等到长度等于digits的时候记录结果集
if index == len(digits) {
ret = append(ret, string(cur))
return
}
//记录当前传参的数字所代表的字符有哪些
letters := []byte(h[string(digits[index])])
for _, v := range letters {
//按顺序把当前的数字所代表的字符添加到当前字符串后面
cur = append(cur, v)
//当前数字所代表的字符已经记录,下一次添加新的数字所代表的字符
dfs(index+1)
//到这里说明之前的那个字符串已经写入了,所以把刚刚的字符回溯删除,下一次循环写当前数字的还未记录过的字符
cur = cur[:len(cur)-1]
}
}
//调用dfs
dfs(0)
return ret
}
总结
本文是 《算法题目解析系列》 的第 35 篇,本系列将持续更新,每篇都提供清晰的思路与编程语言实现。欢迎关注,第一时间获取更新。如果你有想看的题目,也可以在评论区留言告诉我。