力扣-17-电话号码的字母组合


首先,需要保存数字到字母的映射关系,第一反应当然就是map,确切地说,unordered_map
但其实这里应该是个一对多的关系,想到的要么一个键对应一个字符串,要么多个相同的键

像一个排列组合问题

直接看官方题解是回溯啊,以前也尝试过,感觉回溯好难

让我想起了力扣的回溯模板题——

其实回看这两道题发现他俩其实非常相似,模板大概像是

返回值 主方法(参数){
    声明一个返回值类型对象
    检查输入是否非法
    准备参数
    调用回溯子函数
    返回 返回值
}

返回值 回溯子函数(返回对象,输入参数,临时变量,索引长度,参数){
    if(索引长度==参数长度){
        临时变量放入结果集中
    } //结束条件
    for循环{
        前置操作
        递归调用自身
        复原
    }
}
class Solution {
public:
    vector letterCombinations(string digits) {
        vector combinations;
        if(digits.empty()){
            return combinations;
        }
        unordered_map map{
            {'2', "abc"},
            {'3', "def"},
            {'4', "ghi"},
            {'5', "jkl"},
            {'6', "mno"},
            {'7', "pqrs"},
            {'8', "tuv"},
            {'9', "wxyz"}
        };
        string combination;
        // 我想起来一般回溯法都会有一个回溯子函数
        back_track(combinations,map,digits,0,combination);
        return combinations;
    }
    // 这里细节的点是形参的const关键字,防止参数被更改
    void back_track(vector& combinations,const unordered_map& map,const string& digits,int index,string& combination){
        // 如果组合出的字符长度等于数字位数
        if(index==digits.length()){
            combinations.push_back(combination);
        }else{
            char digit = digits[index];
            // 获取当前索引的数字
            const string& letters = map.at(digit);// 获取数字对应的字符(串)

            for(const char& letter:letters){
                combination.push_back(letter);
                back_track(combinations, map, digits, index + 1, combination);
                combination.pop_back();
                // 回退当前位置插入的元素,换上另一个可能元素
            }
        }
    }
};