题目描述
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母
示例 1:
输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
示例 2:
输入:digits = “”
输出:[]
示例 3:
输入:digits = “2”
输出:[“a”,“b”,“c”]
思路分析
一看到这种组合的题,基本都是回溯。
不过我之前做过一次这道题,那时候没有系统的学回溯,所以用队列做的,队列的思路就是两两字符进行组合匹配,就不多说了。
回溯方法:
先构思出来树,假如输入的是23,大概就是下面这个样子:
横向为for,纵向为递归深度,则本题显然for里就是某个数字对应的字母数。
模板三步走:
1. 确定回溯函数参数值:
肯定要带着题目所给的digits,还要一个参数index,这个index记录当前遍历到digits里的哪一个数的下标。 毕竟要通过这个下标找到这个数对应的字母长度来控制for循环。
def backtrack(digits,index):
2. 确定终止条件:
这道题终止条件有个小坑,index记录的是当前遍历digits中数的下标,所以当index == len(digits) 就return。 这里为啥不是 index == len(digits) -1呢,因为终止条件在下面for循环处理的前面,如果这里 是index == len(digits) -1 就终止了,相当于digits的最后一个元素没处理。
终止之前记着将temp记录数组加入到答案数据集,因为我定义的临时数组temp是列表类型,而人家给的是字符串,所以做个类型变化。这里定义为数组而不是字符串,是方便后面直接用pop(),其实用字符串也是一行代码的事,只不过回溯里写pop写习惯了。
if index==len(digits):
res.append("".join(temp[:]))
return
3.循环体:
还是老套路,回调前面写 本层到下一层要操作的代码,也就是将字母加入到temp临时数组, 回调函数下面写下一层回到本层要做的操作,就是弹出temp里的元素。
这里的循环要注意,刚开始的时候说过了,横向控制的是数字映射的字母个数,所以这里要取出来里面有多少个字母,遍历他们。
for i in d[int(digits[index])]:
temp.append(i)
backtrack(digits,index+1)
temp.pop()
完整代码
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
d = [" ","*","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]
res = []
temp = []
def backtrack(digits,index):
if index==len(digits):
res.append("".join(temp[:]))
return
# print(d[int[digits[index]]])
for i in d[int(digits[index])]:
temp.append(i)
backtrack(digits,index+1)
temp.pop()
backtrack(digits,0)
return [] if res == [""] else res