题目
17. Letter Combinations of a Phone Number
Given a digit string, return all possible letter combinations that the number could represent. A mapping of digit to letters (just like on the telephone buttons) is given below.
用户按数字键,程序输出所有的可能组合。
例子
1 | Input:Digit string "23" |
思路
如果只有两个按键1
、2
,对应[A, B, C]
、[D, E, F]
,那么它有 3×3=9
种组合,为了一个不漏首先从最后一个来变换,也就是先写A
,然后轮流写D
、E
、F
,生成AD
、AE
、AF
后将第一位换为
B,这样有顺序的排列组合可以保证不遗漏所有情况。
接下来就是使用代码实现这种排列组合了,相当于是循环第一位可能对应的字母,每个字母后面再循环第二位可能对应的字母,可以使用递归来实现,但是一般语言递归都有深度限制,题目中未限制用户输入长度,所以需要将递归转换为循环。
如何将递归转换为循环,可以类比生活中箱子上的密码锁,4 位的密码锁如果想破解可能有 10000
种组合,肯定是从0000
开始试,一直到9999
才不会漏掉,假设用户输入的数字每个可以对应 3 种可能,那就可以将这些组合用 3
进制表示,只需要列出0000
、0001
、0002
、0010
到2222
就包含了所有组合,每一位数字对应用户输入所可能映射的列表下表。因为7
、9
对应 4
种字母,所以用 4 进制表示,遇到输入不是7
、9
的就跳过第四种可能。
代码
Python
1 | class Solution(object): |
优化
提交后耗时 60ms,最快的用户是 36ms,这里想到了两种优化方式
- 因为是模拟了 4 进制,数字比较特殊,在做数字与 4 进制变换时,可以用位运算移 2 位来代替除法,应该可以加快速度。
- 可以先跑表,既然可以列出 0-9 对应的字母,那么也可以列出 00-99 所对应的字母,
1
对应[A, B, C]
,那么11
就对应[AA, AB, AC, BA, BB, BC, CA, CB, CC]
。将此表事先写好在程序里,处理用户输入的时候就可以两位两位处理,应该可以加快一倍速度。