回溯算法之电话号码的字母组合
Posted 快乐江湖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了回溯算法之电话号码的字母组合相关的知识,希望对你有一定的参考价值。
解法框架
电话号码的组合(点击跳转)
对于这道题,很明显涉及到的也是回溯算法。但是这道题有一特别之处,就是它的选择列表给的不明显,回想全排列那道题目,其选择列表给出的十分明显。此题之中则是多了一层映射关系,所以必须有一个类似于哈希表的结构保存这种映射关系,这里直接使用vector
即可
vector<string> map={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};//选择列表
首先,这道题的形参是一个字符串,这个字符串中有若干数字字符,每个字符都对应了相应的字母列表,函数的返回值是一个一维数组,数组的每个元素是一个字符串,字符串里保存的是满足条件的组合
因此摆出,回溯算法基本框架
接下来编写递归函数back,路径肯定是track,但是选择列表呢?是选择digits呢还是map呢,其实这也是本题的一个难点。以“23”为例,其决策树如下
可以发现这种对应关系有些“奇怪”,让人很难受,它并不是单纯的对应,其难受点就在于这个数字和字母的对应上。比如当处理2时,第一个加入路径的是a,然后此时下一个应该选择d,但是问题就在这里,d对应的是数字3,已经不是2的范畴了。所以这个选择列表应该有两部分组成,一个是digits,一个是index,index用于控制数字。每次进入递归时,根据index拿到数字,然后根据数字在map中找到对应的字母列表,然后开始选择操作。
class Solution {
public:
vector<string> ret;//返回结果
vector<string> map={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};//选择列表
vector<string> letterCombinations(string digits)
{
string track;//路径
if(digits.size()==0)//特殊情况
{
return ret;
}
back(track,digits,0);
return ret;
}
void back(string track,string digits,int index)//遍历决策树
{
if(track.size()==digits.size())//一条路径已经走完,可以加上这种情况
{
ret.push_back(track);
return;
}
int pos=digits[index]-'0';//根据index拿出数字,所以pos就决定了要选择哪个按键上的字母
string temp=map[pos];//temp里保存的就是字母
for(int i=0;i<temp.size();i++)//遍历选择列表
{
track.push_back(temp[i]);//做出选择
back(track,digits,index+1);//遍历决策树,index肯定要加1,因为
//一个按键上只能选择一个字母
track.pop_back();//撤销选择
}
}
};
所以这道题相较于全排列来说就多了一层映射关系。在全排列时我们选择数字不能出现重复,其实这里也是一样,我们选择字母不能第一次和第二次都在一个按键上选择字母
以上是关于回溯算法之电话号码的字母组合的主要内容,如果未能解决你的问题,请参考以下文章
leetcode 17. 电话号码的字母组合----回溯算法
Leetcode之回溯法专题-17. 电话号码的字母组合(Letter Combinations of a Phone Number)