每日一道leetcode(补充版)

发布于:2025-05-07 ⋅ 阅读:(5) ⋅ 点赞:(0)

17. 电话号码的字母组合 - 力扣(LeetCode)

题目

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

示例 2:

输入:digits = ""
输出:[]

示例 3:

输入:digits = "2"
输出:["a","b","c"]

提示:

  • 0 <= digits.length <= 4
  • digits[i] 是范围 ['2', '9'] 的一个数字。

思路

  1. 因为按键中不完全有规律,所以按键和字母的匹配最好是使用哈希字典存储。
  2. 维护一个全局的结果数组,每次取出第一个数后执行以下步骤:
    1. 若结果数组为空,则将该按键的字母分别插入;如果不为空,则不断地取出数组中的元素各自接上新按键的字母再插回数组,然后删除被去取出的元素。
    2. 删除被取出的数,继续往下递归。

代码实现

class Solution {
public:
    vector<string> ans;
    unordered_map<char, string> num_dict = {{'2',"abc"}, {'3',"def"}, {'4',"ghi"}, {'5',"jkl"}, {'6',"mno"}, {'7',"pqrs"}, {'8',"tuv"}, {'9',"wxyz"}};
    void letterInput(string digits) {
        string characters, str;
        if(!digits.size()) return;
        int n = ans.size();
        characters = num_dict[digits[0]];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < characters.size(); j++) {
                str = ans[0];
                str += characters[j];
                ans.push_back(str);
            }
            ans.erase(ans.begin());
        }
        digits.erase(digits.begin());
        letterInput(digits);
    }
    vector<string> letterCombinations(string digits) {
        string characters, str;
        if(!digits.size()) return ans; 
        int n = ans.size();
        characters = num_dict[digits[0]];
        for(int i = 0; i < characters.size(); i++) {
            str = "";
            str += characters[i];
            ans.push_back(str);
        }
        digits.erase(digits.begin());
        letterInput(digits);
        return ans;
    }
};

复杂度分析

  • 时间复杂度:因为有的按键有4个字母,所以不妨取个上界,统一考虑为有4个字母的按键,则每个位置都有四种可能,共有n个位置,所以总的可能性有4*4*...*4=4^n,即O(4^n)。
  • 空间复杂度:忽略结果数组的话,空间复杂度取决于递归的深度,最大为n,所以空间复杂度为O(n)。若考虑结果数组,则空间复杂度也就是需要存储的可能性数,等价于时间复杂度。

网站公告

今日签到

点亮在社区的每一天
去签到