问题
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
思路
以上面示例为例:
“2” 和 “3” 对应的是["a", "b", "c"]
和 ["d", "e", "f"]
之间所有的组合情况。在所产生的结果结构如下:
这实际上可以看作是A = { a, b, c }
和 B = {d, e, f}
这两个集合的笛卡尔积运算, 为A × B
。
如果有第三个数字4,对应集合C = { g, h, i }
,则结果为A × B × C
。
所以步骤为:
- 列出数字对应的集合列表
[ A, B, C, ...]
- 计算
A × B × C × ...
代码
// 数字 2 - 9 对应的字母集合
const PhoneChart = [
['a', 'b', 'c'],
['d', 'e', 'f'],
['g', 'h', 'i'],
['j', 'k', 'l'],
['m', 'n', 'o'],
['p', 'q', 'r', 's'],
['t', 'u', 'v'],
['w', 'x', 'y', 'z']
]
/**
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function(digits) {
// 示输入为空为空就可以提前退出了
if(digits.length <= 0) return []
// 获取集合列表
const letters = digits.split('').map(index => PhoneChart[index - 2])
let rs = letters[0]
// 对集合列表中的项挨个进行“笛卡尔积”计算
for(let i = 1; i < letters.length; i++) {
rs = [].concat(...letters[i].map(addon => rs.map(pre => pre + addon)))
}
return rs
};