题目:
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
思路:实际上是一个排列组合的问题。使用了回溯的思想。
代码:
根据网上大神思路改的代码
class Solution {
static String[] a = new String[] {"","","abc","def", //将数字与字符串一一映射,注意前两个均为空
"ghi","jkl","mno","pqrs","tuv","wxyz"};
static StringBuffer sb = new StringBuffer(); //用来存放每一种组合字符串
public List<String> letterCombinations(String digits) {
if (digits.length() == 0) {
List<String> answers = new ArrayList<String>();
return answers;
}
List<String> answer = new ArrayList<String>(); //存放所有组合最后的结果
//开始回溯
zuhe(digits , 0 , answer);
return answer;
}
private static void zuhe(String digits , int n, List<String> answer) {
if (n == digits.length()) {
answer.add(sb.toString());
return;
}
for (int i = 0; i < a[digits.charAt(n)-'0'].length(); i++) { //遍历数字对应的字符串
sb.append(a[digits.charAt(n)-'0'].charAt(i));
zuhe(digits, n + 1, answer);
sb.deleteCharAt(sb.length() - 1); //删除 添加的字符
}
}
}
回溯:
(参考网上的文章)
从问题的某一种可能出发, 搜索从这种情况出发所能达到的所有可能, 当这一条路走到” 尽头 “的时候, 再倒回出发点, 从另一个可能出发, 继续搜索. 这种不断” 回溯 “寻找解的方法, 称作” 回溯法 “。
回溯是一种算法思想,可以用递归实现。通俗点讲回溯就是一种试探,类似于穷举,但回溯有“剪枝”功能,比如求和问题。给定7个数字,1 2 3 4 5 6 7求和等于7的组合,从小到大搜索,选择1+2+3+4 =10>7,已经超过了7,之后的5 6 7就没必要在继续了,这就是一种搜索过程的优化。
执行最快的代码:
也是使用回溯的思想,在一些细节上的处理不同。添加的时候直接使用字符串相加,没有使用stringbuffer,也没有删除的操作
class Solution {
String[] nums = new String[]{
"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"
};
String digits;
public void build(List<String> list, int num, String pre) {
if(num == digits.length()) {
list.add(pre);
} else {
for(int i = 0; i < nums[digits.charAt(num) - '0'].length(); i++) {
build(list, num + 1, pre + nums[digits.charAt(num) - '0'].charAt(i));
}
}
}
public List<String> letterCombinations(String digits) {
this.digits = digits;
List<String> result = new ArrayList<>();
build(result, 0, "");
if(result.size() == 1 && result.get(0).equals("")) {
return new ArrayList<String>();
}
return result;
}
}