题目:给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
原题链接:回溯算法:leetcode77.组合_L-KKKKK的博客-CSDN博客
此题也是回溯算法的经典题目:与上篇文章“组合”相比较,“组合”是在一个集合中进行组合,而此题目是从两个集合中进行组合。只不过这里需要对数字及其映射的字母做处理,这里我们使用map的key,value来映射数字和字母:
class Solution {
//结果集
List<String> result = new ArrayList<String>();
//map来映射数字和字母
Map<Character,String> map = 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) {
if(digits.length() == 0){
return result;
}
backtracking(new StringBuffer(),digits,0);
return result;
}
//回溯方法实现
public void backtracking(StringBuffer sb,String digits,int index){
//
if(sb.length() == digits.length()){
//将已经符合要求的sb,存入result中
result.add(sb.toString());
return;
}
//通过index来找digits对应的字符 ①
char ch = digits.charAt(index);
//通过ch在map中找对应的值 ②
String str = map.get(ch);
//获取str的长度,为后面的横向遍历做准备 ③
int len = str.length();
//纵向遍历
for(int i = 0; i < len; i++){
//遍历拼接sb
sb.append(str.charAt(i));
//递归纵向遍历
//这里的index要加一,这里的index目的是为了跟踪digits,为了①②③做准备
backtracking(sb,digits,index + 1);
//回溯,这部尤其重要,将上一步拼接好的sb的最后一个字符删掉(因为拼接好的sb已经加入到result中了),为下一次递归拼接腾出位置
sb.deleteCharAt(sb.length() - 1);
}
}
}
在 回溯算法:leetcode77.组合_L-KKKKK的博客-CSDN博客中回溯时也涉及到了一个参数startIndex,横向遍历时(for)i从startIndex开始是因为从一个集合中进行组合,为了避免元素重复被选中,就从startIndex开始。而此题涉及到两个甚至多个集合,也就不存在一个集合中元素被重复选中的问题了。