LeetCode17 —— 电话号码的数字组合
题目:
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:"23" 输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
方法一:回朔法
回溯是一种通过穷举所有可能情况来找到所有解的算法。如果一个候选解最后被发现并不是可行解,回溯算法会舍弃它,并在前面的一些步骤做出一些修改,并重新尝试找到可行解。
说白了,这一题也就是在循环里面来循环。

思路如上图,如果输入两个字符,循环两次,输入三个字符,循环三次,输入n个字符,循环n次,但是程序不能这么搞啊,
所以就想到了循环递归。那么就可以另外定义一个函数,用于递归。代码如下:
tel = {
'2': ['a', 'b', 'c'],
'3': ['d', 'e', 'f'],
'4': ['g', 'h', 'i'],
'5': ['j', 'k', 'l'],
'6': ['m', 'n', 'o'],
'7': ['p', 'q', 'r', 's'],
'8': ['t', 'u', 'v'],
'9': ['w', 'x', 'y', 'z']
}
def backup(combation, next_digit):
# 递归出口
if len(next_digit) == 0:
output.append(combation)
else:
for i in tel[next_digit[0]):
backup(combation+i, next_digit[1:])
很容易看出,输入多少个字符,就会开启多少个循环,等到最内层的循环结束,再返回最内存的外一层循环,就这样依次向外返回,直至最外层的循环也结束,整个递归也就结束了。
图就不画了,细细品味也能理解。完整的代码如下:
def letterCombinations(digits: str) -> list: tel = { '2': ['a', 'b', 'c'], '3': ['d', 'e', 'f'], '4': ['g', 'h', 'i'], '5': ['j', 'k', 'l'], '6': ['m', 'n', 'o'], '7': ['p', 'q', 'r', 's'], '8': ['t', 'u', 'v'], '9': ['w', 'x', 'y', 'z'] } def backup(combation, next_digit): if len(next_digit) == 0: output.append(combation) else: for i in tel[next_digit[0]]: backup(combation + i, next_digit[1:]) output = [] if digits: backup('', digits) return output
方法二:队列法
利用队列的先进先出规则,思想如下:弹出队列中的第一个元素,与输入字符对应的字母依次拼接,再添加至队列中

过程如下,估计看了这个,就基本明白了吧,直接上代码了。
1 def letterCombinations_v2(digits: str) -> list: 2 ret = [''] 3 d = ['', '', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz'] 4 for i in digits: 5 letter = d[ord(i) - 48] 6 7 length = len(ret) 8 9 for _ in range(length): 10 tmp = ret.pop(0) 11 12 for l in letter: 13 ret.append(tmp + l) 14 15 return ret

浙公网安备 33010602011771号