class Solution {
public static void backtrack(String digits,Map<Character, String> map,List<String> res,int index,StringBuffer pre) {
if(index==digits.length()) {
res.add(pre.toString());
}else {
char c_num=digits.charAt(index);
String str=map.get(c_num);
int len = str.length();
for(int i = 0;i < len;i++) {
pre.append(str.charAt(i));
backtrack(digits, map, res, index+1, pre);
pre.deleteCharAt(index);
}
}
}
public List<String> letterCombinations(String digits) {
List<String> res=new LinkedList<String>();
if(digits.length()==0) {
return res;
}
Map<Character, String> map=new HashMap<Character, String>();
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");
backtrack(digits,map,res,0,new StringBuffer());
return res;
}
}
Backtracking(回溯)属于 DFS。
- 普通 DFS 主要用在可达性问题,这种问题只需要执行到特点的位置然后返回即可。
- 而 Backtracking 主要用于求解排列组合问题,例如有 { ‘a’,‘b’,‘c’ } 三个字符,求解所有由这三个字符排列得到的字符串,这种问题在执行到特定的位置返回之后还会继续执行求解过程。
因为 Backtracking 不是立即返回,而要继续求解,因此在程序实现时,需要注意对元素的标记问题:
- 在访问一个新元素进入新的递归调用时,需要将新元素标记为已经访问,这样才能在继续递归调用时不用重复访问该元素;
- 但是在递归返回时,需要将元素标记为未访问,因为只需要保证在一个递归链中不同时访问一个元素,可以访问已经访问过但是不在当前递归链中的元素。