【算法训练】LeetCode#17 电话号码的字母组合
一、描述
17. 电话号码的字母组合
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = ""
输出:[]
示例 3:
输入:digits = "2"
输出:["a","b","c"]
二、思路
九键党永不为奴(不是
先用暴力枚举,试一试能不能ac。
过了....官方题解是回溯
三、解题
public class LeetCode17 {
public static List<String> letterCombinations(String digits) {
if (digits == null || digits.length() < 1){
return new LinkedList<String>();
}
HashMap<Character,char[]> map = new HashMap<>();
map.put('2',new char[]{'a','b','c'});
map.put('3',new char[]{'d','e','f'});
map.put('4',new char[]{'g','h','i'});
map.put('5',new char[]{'j','k','l'});
map.put('6',new char[]{'m','n','o'});
map.put('7',new char[]{'p','q','r','s'});
map.put('8',new char[]{'t','u','v'});
map.put('9',new char[]{'w','x','y','z'});
int n = 1;
for (int i = 0 ; i < digits.length() ; i++){
int size = map.get(digits.charAt(i)).length;
n *= size;
}
// 一共有n种情况
String[] ans = new String[n];
int digitsLen = digits.length();
int scale = 1; // 循环次数
int curSize = 1; // 每个字母重复次数
// 模拟全排列
for (int i = 0 ; i < digitsLen ; ++i){
int loc = 0; // ans的索引
char[] chars = map.get(digits.charAt(i)); // 当前数字对应的字母
curSize *= chars.length;
for (int j = 0 ; j < scale ; ++j){
for (char ch : chars){
// 遍历并写入ans
for (int k = 0 ; k < n/curSize ; k++){
// 重复写
ans[loc] = ans[loc]==null ? String.valueOf(ch) : ans[loc]+ch;
++loc;
}
}
}
scale *= chars.length; // 重复的次数是上一轮的size
}
return new LinkedList<>(Arrays.asList(ans));
}
public static void main(String[] args) {
System.out.println(letterCombinations("234"));
}
}