力扣热题100 - 回溯:电话号码的字母组合

题目描述:

题号:17

图片

解题思路:

思路一:回溯

解题的核心思想是使用回溯算法(Backtracking)。

主要步骤

  1. 数据结构初始化:

    • 使用一个 unordered_map 来存储电话号码数字到对应字母的映射。例如,'2' 对应 "abc",'3' 对应 "def" 等。

  2. 边界条件检查:

    • 如果输入的 digits 字符串为空,则直接返回一个空的结果集。

  3. 回溯函数:

    • 定义一个名为 backtrack 的递归函数,它负责生成所有可能的字母组合。

    • 函数参数包括:结果集 combinations、输入的数字字符串 digits、当前处理的索引 index 以及当前正在构建的字母组合 combination

  4. 递归逻辑:

    • 将字母添加到 combination 中。

    • 递归调用 backtrack 处理下一个数字。

    • 在递归返回后,从 combination 中移除刚刚添加的字母(这是回溯的关键步骤,确保能够尝试所有可能的组合)。

    • 如果 index 等于 digits 的长度,说明已经处理完所有数字,将当前构建的 combination 添加到结果集中。

    • 否则,取出当前索引对应的数字,并根据这个数字从 phoneMap 中获取对应的字母字符串。

    • 对这个字母字符串中的每个字母,执行以下操作:

  5. 启动回溯:

    • 在 letterCombinations 函数中,初始化一个空的 combination 字符串,并从索引 0 开始调用 backtrack 函数。

  6. 返回结果:

    • letterCombinations 函数最终返回包含所有可能字母组合的 combinations 向量。

本题关键点在于找出数字和字母的映射关系。

时间复杂度:O(4 ^ N)

空间复杂度:O(4 ^ N) 

C++

// C++
class Solution {
    unordered_map<char, string> phoneMap {
            {'2',"abc"},
            {'3',"def"},
            {'4',"ghi"},
            {'5',"jkl"},
            {'6',"mno"},
            {'7',"pqrs"},
            {'8',"tuv"},
            {'9',"wxyz"}
        };
public:
    vector<string> letterCombinations(string digits) {
        vector<string> combinations;
        if (digits.empty() == true) {
            return {};
        }
        
        string combination;
        backtrack(combinations, digits, 0, combination);
        return combinations;
    }

    void backtrack(vector<string>& combinations, const string& digits, int index, string& combination) {
        if (index == digits.length()) {
            combinations.push_back(combination);
        } else {
            char digit = digits[index];
            const string& letters = phoneMap.at(digit);
            for (const char& letter: letters) {
                combination.push_back(letter);
                backtrack(combinations, digits, index + 1, combination);
                combination.pop_back();
            }
        }
    }
};

go


// go
func letterCombinations(digits string) []string {
    if len(digits) == 0 {
        return nil
    }
    combinations = []string{}
    backtrack(digits, 0, "")
    return combinations
}

func backtrack(digits string, index int, combination string) {
    if index == len(digits) {
        combinations = append(combinations, combination)
    } else {
        digit := string(digits[index])
        letters := phoneMap[digit]
        lettersCount := len(letters)
        for i := 0; i < lettersCount; i++ {
            backtrack(digits, index + 1, combination + string(letters[i]))
        }
    }
}

var combinations []string

var phoneMap map[string]string = map[string]string{
    "2": "abc",
    "3": "def",
    "4": "ghi",
    "5": "jkl",
    "6": "mno",
    "7": "pqrs",
    "8": "tuv",
    "9": "wxyz",
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值