题目介绍
力扣17题:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
分析
给定数字之后,我们需要遍历每个数字对应字母的所有可能,然后进行组合。题目要求我们返回所有可能的字母组合,所以需要穷举所有解。
于是自然想到,我们可以用回溯算法来解决。依次遍历数字,选取可能的字母;递归地进行搜索,直到找到一个可行解,然后进行回溯继续遍历。
代码实现
可以用一个哈希表把数字对应的字母存储起来,方便快速查询。
代码如下:
public class LetterCombinationsOfPhoneNumber {
// 定义一个HashMap,保存数字对应的字母
HashMap<Character, String> numberMap = new HashMap<Character, String>() {
{
put('2', "abc");
put('3', "def");
put('4', "ghi");
put('5', "jkl");
put('6', "mno");
put('7', "pqrs");
put('8', "tuv");
put('9', "wxyz");
}
};
public List<String> letterCombinations(String digits) {
ArrayList<String> result = new ArrayList<>();
if ("".equals(digits)) return result;
StringBuffer combination = new StringBuffer();
// 从第一个数字开始回溯处理
backtrack(digits, result, combination, 0);
return result;
}
// 定义一个回溯方法
public void backtrack(String digits, List<String> result, StringBuffer combination, int i){
int n = digits.length();
if (i >= n){
result.add(combination.toString());
} else {
char digit = digits.charAt(i);
String letters = numberMap.get(digit);
// 遍历所有可能的字母
for (int j = 0; j < letters.length(); j++){
combination.append(letters.charAt(j));
// 递归调用,继续处理后续数字
backtrack(digits, result, combination, i + 1);
// 回溯
combination.deleteCharAt(i);
}
}
}
}
复杂度分析
- 时间复杂度:O(3^m * 4^n),其中 m 是输入中对应 3 个字母的数字个数,n 是输入中对应 4 个字母的数字个数,m+n就是输入数字的总个数。需要遍历每一种字母组合,总共是3^m * 4^n种组合。
- 空间复杂度:O(m+n)。除了返回结果外,空间复杂度主要取决于回溯的递归调用深度,最大为m+n。而哈希表的大小与输入无关,可以看成常数。