Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.
Example:
Input: “23”
Output: [“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.
这道题自己只想到了暴力解法。
即将所有数字对应的字母通过循环依次取出来,然后进行嵌套遍历的方法。借助 HashMap 存储数字与字母间的键值关系。
其中循环嵌套思路为:
class Solution {
public List<String> letterCombinations(String digits) {
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");
List<String> list = new ArrayList<>();
if(digits.length()==0) {
return list;
}
list.add("");
for(int i=0; i<digits.length(); i++) {
List<String> temp = new ArrayList<>();
String substr = map.get(digits.charAt(i));
for(String str: list) {
for(int j=0; j<substr.length(); j++) {
String strsum = str + substr.charAt(j);
temp.add(strsum);
}
}
list = temp;
}
return list;
}
}
或者,也可利用队列先进先出的性质进行横向组合
思路:
class Solution {
public List<String> letterCombinations(String digits) {
LinkedList<String> res = new LinkedList<>();
String[] map = new String[] {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
if(digits.length()==0) {
return res;
}
res.add("");
while(res.peek().length() != digits.length()) {
String temp = res.pop();
String str = map[digits.charAt(temp.length()) - '0'];
for(char c: str.toCharArray()) {
res.add(temp + c);
}
}
return res;
}
}
这种方法代码简洁一些,但与解法一思路相同,因此时间复杂度也相同。
“回溯”算法:即一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择。
大部分回溯问题都离不开几个元素:递归、深度优先以及全排列
分析题目可知:题目的输出近似是一种将满足条件所有排列都枚举出来。即每次固定一个位置改变其他位置
若输入的数为“234”,那么第一个字符有三种选择,分别是“a”,“b”,“c”,如果第一个字符选 a,那么第二个字符也有 3 种选择,而选择好第二个字符后,第三个字符又有3种选择…以此类推会发现,这个逻辑思路与树结构很像,都是一层层增多,每一层的一个节点都对应有多个孩子节点。
因此可以用“回溯”的思路求解。
class Solution {
private static final String[] map = new String[] {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
public List<String> letterCombinations(String digits) {
List<String> res = new ArrayList<>();
if(digits.length()==0) {
return res;
}
doCombination(new StringBuffer(), res, digits);
return res;
}
private void doCombination(StringBuffer str, List<String> res, String digits) {
//str达到预期长度,即完成一次组合,就将str保存进res中
if(str.length() == digits.length()) {
res.add(str.toString());
return;
}
//读取当前digits遍历到的元素对应的可选字符集
String substr = map[digits.charAt(str.length())-'0'];
//遍历可选字符集,每次固定当前位置的字符,再进行下一位的字符选择
for(char c: substr.toCharArray()) {
str.append(c); //添加
doCombination(str, res, digits); // 递归
str.deleteCharAt(str.length() - 1); //删除
}
}
}