LeetCode hot 100—电话号码的字母组合

题目

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

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

示例

示例 1:

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

示例 2:

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

示例 3:

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

分析

回溯

时间复杂度:O(3^{m}\times 4^{n}), m 输入数字中对应 3 个字母的数字个数,n 是输入数字中对应 4 个字母的数字个数

空间复杂度:O(m+n)

class Solution {
private:
    // 定义数字到字母的映射
    std::unordered_map<char, std::string> phoneMap = {
        {'2', "abc"},
        {'3', "def"},
        {'4', "ghi"},
        {'5', "jkl"},
        {'6', "mno"},
        {'7', "pqrs"},
        {'8', "tuv"},
        {'9', "wxyz"}
    };
    std::vector<std::string> result;
    std::string current;

    // 回溯函数
    void backtrack(const std::string& digits, int index) {
        if (index == digits.length()) {
            // 当遍历完所有数字,将当前组合加入结果集
            result.push_back(current);
            return;
        }
        char digit = digits[index];
        std::string letters = phoneMap[digit];
        for (char letter : letters) {
            // 选择当前字母
            current.push_back(letter);
            // 递归调用,处理下一个数字
            backtrack(digits, index + 1);
            // 回溯,撤销选择
            current.pop_back();
        }
    }

public:
    std::vector<std::string> letterCombinations(std::string digits) {
        if (digits.empty()) {
            return {};
        }
        backtrack(digits, 0);
        return result;
    }
};    

知识充电

回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。

模板

#include <vector>

// 回溯函数模板
void backtrack(std::vector<int>& path, std::vector<int>& choices, std::vector<std::vector<int>>& result) {
    // 终止条件:判断是否满足解的条件
    if (isSolution(path)) {
        result.push_back(path);
        return;
    }
    // 遍历所有可能的选择
    for (int choice : choices) {
        // 做出选择
        if (isValid(choice, path)) {
            path.push_back(choice);
            // 递归调用,继续搜索
            backtrack(path, choices, result);
            // 撤销选择
            path.pop_back();
        }
    }
}

// 判断是否为一个有效的解
bool isSolution(const std::vector<int>& path) {
    // 这里根据具体问题实现判断逻辑
    // 例如,当 path 的长度达到某个值时认为是一个解
    return path.size() == 某个特定长度;
}

// 判断当前选择是否有效
bool isValid(int choice, const std::vector<int>& path) {
    // 这里根据具体问题实现判断逻辑
    // 例如,检查选择是否已经在 path 中出现过
    for (int p : path) {
        if (p == choice) {
            return false;
        }
    }
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rigidwill666

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值