【practise】电话号码的字母组合

关于我:在这里插入图片描述


睡觉待开机:个人主页

个人专栏: 《优选算法》《C语言》《CPP》
生活的理想,就是为了理想的生活!
作者留言

PDF版免费提供倘若有需要,想拿我写的博客进行学习和交流,可以私信我将免费提供PDF版。
留下你的建议倘若你发现本文中的内容和配图有任何错误或改进建议,请直接评论或者私信。
倡导提问与交流关于本文任何不明之处,请及时评论和私信,看到即回复。



1.前言

今天来分享一道比较中规中矩的题目题解,即电话号码的组合。这道题思路上来说很简单,但是前提得理解深度优先遍历


什么是深度优先遍历?
在这里插入图片描述

举个例子,二叉树的中序遍历(当然二叉树的前序、后序遍历也属于深度优先遍历),按照左子树、根、右子树的方式依次遍历整棵树。

在这里插入图片描述


2.题目介绍

题目链接:LINK
在这里插入图片描述
这道题题意很简单,给到我们一个字符串,然后字符串里有一些数字字符,每个数字字符对应一个特定的字母字符串,挨个取字母字符串元素,取出所有组合即可。

比如,给到我们的数字字符串是:“234”,那我们的遍历图解如下:
在这里插入图片描述

3.题解思路

我们的整体思路使用哈希表存储每个字符数字对应的所有可能的字母,并对其进行回溯。

回溯的过程:我们用一个string类型来维护我们每次维护的字符串结果,得到每个string结果之后,将其尾插到返回结果中去。
该字符串初始为空,每次取电话号码中的一位数字,然后根据这个数字获得该数字对应的所有可能的字母,将其中的一个字母插入到我们维护的string中,然后继续处理电话号码的后一位数字,知道处理完电话号码中的所有数字,即得到一个完整的字母排列。然后进行回退操作,遍历其余的字母排列。

4.代码示例

class Solution {
public:
    vector<string> letterCombinations(string digits) {
        vector<string> combinations;//用来返回最后的组合结果
        if(digits.empty())//如果为空,返回个空vector即可
        {
            return combinations;
        }

        //下面开始处理一般情况:
        //先制作了哈希表
        unordered_map<char, string> phoneMap{
            {'2', "abc"},
            {'3', "def"},
            {'4', "ghi"},
            {'5', "jkl"},
            {'6', "mno"},
            {'7', "pqrs"},
            {'8', "tuv"},
            {'9', "wxyz"}
        };
        string combination;//用来存储每个组合,即一个字符串
        backtrack(combinations, combination, digits, phoneMap, 0);
        
        //返回
        return combinations;
    }
    void backtrack(vector<string>& combinations, string& combination, const string& digits, const unordered_map<char, string>&phoneMap, int index)
    {
        //当下标取到digit末尾时候,表示完成了一个string制作,要把它加入到combinations中去
        if(index == digits.size())
        {
            combinations.push_back(combination);
        }
        else//如果不是,那我们先取digits中的数字,再根据数字拿到对应的string,再取string中所需要的那一位
        {
            char digit = digits.at(index);
            const string& letters = phoneMap.at(digit);
            for(auto& letter : letters)
            {
                combination.push_back(letter);
                backtrack(combinations, combination, digits, phoneMap, index+1);
                combination.pop_back();
            }
        }
    }
};

5.时间/空间复杂度分析

注意:m指的是给定的一串数字中对应3位字母的数字的个数,n指得是一串数字中对应4位字母得数字得个数。

时间复杂度:O(3^m + 4^n)
时间复杂度主要就是取决于数字长度了,假定每个数字都对应3个字母,那么就是数字个数的三次方,但是存在部分数字是对应四个字母的,所以应该是上面所示。
空间复杂度:O(m + n)
空间复杂度主要取决于两部分,一部分是哈希表,另一部分是我们调用得递归函数所对应的空间开销。其中由于哈希表底层实现,哈希表的空间复杂度为O(1),调用的递归函数最大递归层级就是给定的字符串数字的长度次。



好的,如果本篇文章对你有帮助,不妨点个赞~谢谢。

在这里插入图片描述


EOF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值