题目:
电话号码的字母组合
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 :
输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
一、算法介绍
- 回溯算法:是一种暴力搜索方法。
主要应用于以下问题:
1)组合问题:N个数⾥⾯按⼀定规则找出k个数的集合;
2)切割问题:⼀个字符串按⼀定规则有⼏种切割⽅式;
3)⼦集问题:⼀个N个数的集合⾥有多少符合条件的⼦集;
4)排列问题:N个数按⼀定规则全排列,有⼏种排列⽅式;
5)棋盘问题:N皇后,解数独等等。
【注:本次主要说明组合问题。】 - 回溯算法模版:
void backtracking(参数) {
if(终止条件) {
存放结果;
returns;
}
for(选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表);//递归
回溯,撤销处理结果
}
}
二、解题思路
- 图解:
遍历的深度是输入’‘23’'的长度,叶子节点(图中红色字母一行)是我们要收集的结果。输入的字符长度是2则遍历两次,是3则遍历三次…依次递推,如果长度过长时不适合用for循环嵌套来解决应用回溯算法。先找到ad,然后把d删除再回退到子节点,然后再找到e,就得到ae,依次类推的一个回溯过程。 - 回溯算法解题思路:
1)**确定回溯函数参数:**以下记录了所有需要用到的变量和参数,具体的传入内容需要根据代码具体分析。
a)准备结果存储空间来收集结果;
List<String> list = new ArrayList<>();
b)定义一个字符串来存储回溯过程中的字符;
StringBuilder builder = new StringBuilder();
c)数字到字母的映射;
String[] letters = {
"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
d)输入的字符串;
String digits = "23";
e)记录遍历的第几个数字
int index
2)**确定终止条件:**例如输入"23",两个数字,那么根节点往下递归两层就可以了,叶子节点就是要收集的结果集。那么终止条件就是如果index等于输⼊的数字个数(digits.size)了(本来index就是⽤来遍历digits的)。然后收集结果,结束本层递归。
if(index == digits.length()){
list.add(builder.toString());
}
3)**确定单层遍历逻辑:**首先要找到输入字符串digits第一个数字所对应的字符组合,然后得到该字符组合的长度,再用for循环来处理。
int l = digits.charAt(index) - '2';
String s