给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。(图与手机的9宫格键盘一样)
开始想的是多重循环,但是字母长度是不确定,这么做肯定是不现实的。 于是很自然就想到了回溯算法,本质还是多重循环。
这里也让我想起了之前看的《啊啥 算法》一书中的深度优先算法推导中的例子了。
public List<String> letterCombinations(String digits) {
if (digits == null || digits.equals("")) {
return result;
}
findLatter(digits, 0, "");
return result;
}
// 这个数组用于将数字转化为对应的字符串
String[] latterMap = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
List<String> result = new ArrayList();
/**
* index是指第几位,s指已经拼凑的字符
**/
public void findLatter(String digits, int index, String s) {
if (digits.length() == s.length()) {
// 满足要求
result.add(s);
return;
}
// 在第index位上的数字
char c = digits.charAt(index);
// 对应数字上的字符
String latters = latterMap[c - '0'];
// 像这种多层循环的场景, 一定要想到回溯的方法。
// 这里本质还是多层循环的方式
// 当前位置上的选择,同时将当前组合的结果传递给下一次递归调用。
for (int i = 0; i < latters.length(); i++) {
// 利用回溯的思想将多层的循环转化为一层循环
findLatter(digits, index + 1, s + String.valueOf(latters.charAt(i)));
}
}
这个例子与之前的不同之处在于, 这里会将当前的结果通过参数传递给下一次调用。 在面对不同类型的回溯算法问题时,可以尝试此种方法。