思路:
每当遇到让写出 所有组合 的题,基本上都是回溯法。
回溯法的套路:
allroutes//在递归函数体外定义一个集合保存所有路径组合
public void findall(list, route, depth)//list保存所有可选的分支,route保存当前到达的路径,depth表示应该到达多深
{
if(route.depth == depth)//当前路径已经到达了最大深度
{
allroutes.add(route.copy);//将当前路径加入allroutes,注意必须保存它的拷贝,因为route是不断在变化的,最终会回到空的状态
return;
}
for(l:list)//遍历所有分支
{
if(route.contains(l))//如果当前路径已经有这个分支,说明已经走过了,跳过该分支
coutinue;
else
{
route.add(l);//如果当前路径中没有这个分支,说明还没走过这个分支,加入当前路径
findall(list,route,depth);//找到当前路径为基础下的所有深度到达depth的路径组合
route.delete(l);//将路径恢复到之前的状态,以便下一次循环
}
}
}
//当递归函数结束的时候,allroutes中就保存了所有的路径组合了
这道题完全可以直接套用回溯法的套路,而且连判断分支是否已经存在于route中都不需要,因为对于当前路径,继续往下走只有一个选择,那就是下一位数字 digits[route.length]
class Solution {
List<String> list = new ArrayList<>();
public void find(HashMap<Character,String> map, String digits,StringBuffer route)
{
if(route.length()==digits.length())
{
list.add(route.toString());
return;
}
char c = digits.charAt(route.length());
String m = map.get(c);
for(int i=0;i<m.length();i++)
{
route.append(m.charAt(i));
find(map,digits,route);
route.deleteCharAt(route.length()-1);
}
}
public List<String> letterCombinations(String digits) {
int n = digits.length();
if(n==0)
return list;
char[] cs = digits.toCharArray();
List<String> res = new ArrayList<>();
HashMap<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");
find(map,digits,new StringBuffer());
return list;
}
}