算法思想
Backtracking(回溯)
属于DFS。
- 普通DFS主要用在可达性问题,这种问题只需要执行到特定点的位置然后返回即可
Backtracking(回溯)
主要用于解决排列组合问题,这种问题在执行到特定的位置返回之后还会继续执行求解过程。
因为 Backtracking(回溯)
不是立即返回,而要继续求解,因此在程序实现时,需要注意对元素的标记问题:
- 在访问一个新元素进入新的递归调用时,需要将新元素标记为已经访问,这样才能在继续递归调用时不用重新访问该元素。
- 在递归返回时,需要将元素标记为未访问,因为只需要保证在一个递归链中不同时访问同一个元素,可以访问已经访问过但是不在当前递归链中的元素。
题目
题目大意
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
解题思路
首先使用哈希表存储每个数字对应的所有可能的字母,然后进行回溯操作。回溯过程维护一个字符串,表示已有的字母排列。每次取电话号码的一位数字,从哈希表中获得改数字对应的所有可能的字母,并将其中的一个字母插入到已有的字母排列后面,然后继续处理电话号码的后一位数字,直到处理完电话号码的所有数字,即得到一个完整的字母排列。然后进行回退操作,遍历其余的字母排列。
代码实现
class Solution {
public List<String> letterCombinations(String digits) {
//保存最终的返回结果
List<String> res=new ArrayList<>();
if(digits.length()==0){
return res;
}
//创建数字与字母的对应map
Map<Character,String> map=new HashMap<>(){{
put('2',"abc");
put('3',"def");
put('4',"ghi");
put('5',"jkl");
put('6',"mno");
put('7',"pqrs");
put('8',"tuv");
put('9',"wxyz");
}};
backtrack(res,map,digits,0,new StringBuffer());
return res;
}
public void backtrack(List<String> res,Map<Character,String> map,String digits,int index,StringBuffer com){
if(index==digits.length()){
res.add(com.toString());
}else{
char c=digits.charAt(index);
String litters=map.get(c);
for(int i=0;i<litters.length();i++){
com.append(litters.charAt(i));
backtrack(res,map,digits,index+1,com);
com.deleteCharAt(index);
}
}
}
}