回溯解决电话号码的字母组合——leetcode17
作者:互联网
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
思路:输入23,暴力法就是直接两层for循环,如果输入233,就是三层for循环。如果输入数字过多,循环次数过多,因此需要用到回溯法。
难点:
-
数字与字母的映射问题
-
两个字母两个for循环,以此类推,发现有难度。
-
输入1 * #按键等等异常情况
-
数字与字母的映射
可以使用map或者二维数组如 string letterMap[10]做映射,如
const string letterMap[10]={
"",//0
"",//1
"abc",//2
"def",//3
"ghi",//4
"jkl"//5
"mno",//6
"pqrs"//7
"tuv"//8
"wxyz",//9
};
- 解决n个for循环问题
将问题抽象成树形结构后:“2,3”的长度就是遍历的深度,叶子节点就是要收集的结果。
回溯的三要素:
- 回溯的参数:字符串s收集叶子节点的结果,字符串数组result保存结果。参数有题中所给string digits,还有一个参数就是int型的index。用来记录遍历第几个数字了,即用来遍历digits(题目中所给数字字符串),同时Index也表示树的深度。
vector<string> result;
string s;
void backtracking(const string& digits,int index)
- 终止条件
如果index等于输入的数字个数(digits.size),就结束。即
if(index == digits.size()){
result.push_back(s);
return;
}
- 单层遍历逻辑
首先要取Index指向的数字,并找到对应的字符集,然后for循环处理该字符集。即
int digit =digits[index]-'0';//将index指向的数字转为int
string letters = letterMap[digit];//取数字对应的字符集
for(int i=0;i<letters.size();i++){
s.push_back(letters[i]);//处理
backtracking(digits,index+1);//递归,注意Index+1,下一层要处理下一个数字
s.pop_back();//回溯
}
这里的for循环并不是像组合问题中从startIndex开始遍历,因为本题的每一个数字代表的是不同集合,而之前的组合都是求同一个集合的组合。
class Solution{
private:
const string letterMap[10]={
"",//0
"",//1
"abc",//2
"def",//3
"ghi",//4
"jkl",//5
"mno",//6
"pqrs",//7
"tuv",//8
"wxyz",//9
};
public:
vector<string> result;
string s;
void backtracking(const string& digits,int index){
if(index == digits.size()){
result.push_back(s);
return;
}
int digit = digits[index]-'0';
string letters =letterMap[digit];
for(int i=0;i<letters.size();i++){
s.push_back(letters[i]);
backtracking(digits,index+1);
s.pop_back();
}
}
vector<string> letterCombinations(string digits){
if(digits.size() ==0){
return result;
}
backtracking(digits,0);
return result;
}
};
标签:digits,index,string,int,leetcode17,result,回溯,字母组合,数字 来源: https://blog.csdn.net/weixin_44097082/article/details/120377270