给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
解题思路
这是一个典型的通过回溯思想来解决的问题,其实就是暴力破解。假设我们先输出
a d
接着,我们退回到按2
的那一步,也就是回到了(这就是回溯法的精髓,我们要有一步回到上一步的操作,这实际上就是可以通过递归去实现的)
a
我们再进入e
,这个时候,我们发现ae
的长度等于23
的长度,所以,我们将ae
添加到结果的result
中去。
a e
这里我要说一下,我们常说的回溯法,其实是一种算法思想,而这种算法思想主要通过递归来实现,并不是说两者等同。
class Solution:
def __init__(self):
self.letterMap = [
' ',
'',
'abc',
'def',
'ghi',
'jkl',
'mno',
'pqrs',
'tuv',
'wxyz'
]
def findCombination(self, digits, index, s, res):
if index == len(digits):
res.append(s)
return
char = digits[index]
letters = self.letterMap[ord(char) - ord('0')]
for letter in letters:
self.findCombination(digits, index + 1, s + letter, res)
def letterCombinations(self, digits):
"""
:type digits: str
:rtype: List[str]
"""
result = list()
if not digits:
return result
self.findCombination(digits, 0, "", result)
return result
一个更pythonic
的写法
class Solution:
def letterCombinations(self, digits):
"""
:type digits: str
:rtype: List[str]
"""
if not digits:
return []
l_map = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl',
'6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'}
chars = [l_map.get(d) for d in digits]
return [''.join(x) for x in itertools.product(*chars)]
这里我们使用到了itertools.product
,实际上表示的是这种操作((x,y) for x in A for y in B)
。
同样的,对于递归可以解决的问题,我们都应该思考是不是可以通过迭代解决。实际上,我们这里在模拟itertools.product
操作。
class Solution:
def letterCombinations(self, digits):
"""
:type digits: str
:rtype: List[str]
"""
result = list()
if not digits:
return result
l_map = {'2':'abc', '3':'def', '4':'ghi', '5':'jkl',
'6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'}
chars = [l_map.get(d) for d in digits]
tmp = [[]]
for pool in chars:
tmp = [x+[y] for x in tmp for y in pool]
for prod in tmp:
result.append(''.join(prod))
return result
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!