题目:
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = ""
输出:[]
示例 3:
输入:digits = "2"
输出:["a","b","c"]
难度:中等
力扣地址:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
解题思路
解法一:队列
(1)首先排除像示例2字符串为空的情况
(2)然后建立一个map映射表,表达出数字对应的字母关系
(3)举个栗子:比方我们给出的字符串是“23”,最开始我们先往队列里面放2对应的三个字符abc。(所以最开始才需要往队列放一个空字符!!)
(4)然后从队列取出“a”,再从字符串“23”里面取出第二个字符3所对应的字母def,把“a”和3对应的字符"d","e","f"挨个拼接。
(5)按照同样的方式,再从队列里取出“b”,再跟3对应的字符"d","e","f"挨个拼接。以此类推。
代码一
class Solution {
public List<String> letterCombinations(String digits) {
if(digits==null || digits.length()==0){
return new ArrayList<String>();
}
//映射表
String[] map_string={ " ","*","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
LinkedList<String> res=new LinkedList<>();
res.add("");//先往队列放一个空字符,否则下面for循环需要考虑第一次队列为空的情况!!
for(int i=0;i<digits.length();i++){
String letter = map_string[digits.charAt(i)-'0'];
int size=res.size();
//计算出队列长度后,把队列的每个元素都挨个拿出来,然后再和后面的字符串拼接
for(int j=0;j<size;j++){
String tmp=res.remove(); //队首元素出队
for(int k=0;k<letter.length();k++){
res.add(tmp+letter.charAt(k));
}
}
}
return res;
}
}
代码二:这个代码看起来会更优雅一些
class Solution {
public List<String> letterCombinations(String digits) {
if(digits==null || digits.length()==0){
return new ArrayList<String>();
}
//映射表
String[] map_string={ " ","*","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
LinkedList<String> res=new LinkedList<String>();
res.add(""); //*********
for(int i=0;i<digits.length();i++){
String letters= map_string[digits.charAt(i)-'0'];
while(res.peek().length()==i){
String tmp=res.remove();//队首元素出队
for(char s:letters.toCharArray())
res.add(tmp+s);
}
}
return res;
}
}
两个代码的时间复杂度都是O(3^m x 4^n),其中 m 是输入中对应 3 个字母的数字个数(包括数字 2、3、4、5、6、8),n 是输入中对应 4 个字母的数字个数(包括数字 7、9),m+n 是输入数字的总个数。当输入包含 m 个对应 3 个字母的数字和 n 个对应 4 个字母的数字时,不同的字母组合一共有 3^m x 4^n 种,需要遍历每一种字母组合。
解法二 回溯法