回溯算法之电话号码的字母组合

Posted 快乐江湖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了回溯算法之电话号码的字母组合相关的知识,希望对你有一定的参考价值。

解法框架

【README】回溯算法基本框架

电话号码的组合(点击跳转)

在这里插入图片描述

对于这道题,很明显涉及到的也是回溯算法。但是这道题有一特别之处,就是它的选择列表给的不明显,回想全排列那道题目,其选择列表给出的十分明显。此题之中则是多了一层映射关系,所以必须有一个类似于哈希表的结构保存这种映射关系,这里直接使用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)

17. 电话号码的字母组合(递归+回溯)

17. 电话号码的字母组合(递归+回溯)

leetcode刷题之回溯法