电话号码的字母组合
题目
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = "" 输出:[]
示例 3:
输入:digits = "2" 输出:["a","b","c"]
提示:
0 <= digits.length <= 4 digits[i] 是范围 ['2', '9'] 的一个数字。
解题分析
解题思路:
核心思路: 回溯
- 对于电话号码的键盘,我们可以先把这些数字和字母的关系通过 Map 做一个映射关系。
- 对于回溯来说,其实本质的过程是是用递归来实现。 首先需要维护一个字符串,表示字母的排列。该字符串初始为空。每次取号码的一位数字,从哈希表中获取对应的所有可能字母, 并将其中的一个字母插入到已有的字母排列后面然后继续处理电话号码的最后一位数字,直到得到一个完整的字母排列。然后进行回退操作,遍历其余的字母排列。
复杂度分析:
时间复杂度:O(3^m X 4^n)
空间负载度:O(m + n)
解题代码
public List<String> letterCombinations(String digits) {
List<String> list = new ArrayList<>();
if (digits.length() == 0) {
return list;
}
Map<Character, String> map = new HashMap<>();
map.put('2', "abc");
map.put('3', "def");
map.put('4', "ghi");
map.put('5', "jkl");
map.put('6', "mno");
map.put('7', "pqrs");
map.put('8', "tuv");
map.put('9', "wxyz");
backtrack(list, map, digits, 0, new StringBuffer());
return list;
}
private void backtrack(List<String> list, Map<Character, String> map, String digits, int index, StringBuffer sb) {
if (index == digits.length()) {
list.add(sb.toString());
} else {
char digit = digits.charAt(index);
String letters = map.get(digit);
int letterCount = letters.length();
for (int i=0; i < letterCount; i++) {
sb.append(letters.charAt(i));
backtrack(list, map, digits, index + 1, sb);
sb.deleteCharAt(index);
}
}
}