Skip to content

代码随想录 回溯算法:电话号码字母组合

题目分类

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

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

img

思考

直接思考,过程就是先从'2'到'9'选一个数字,然后从这个数字对应的字符串中选一个字母。然后就是接着选第二个数字,选再选第二个数字对应的字符串中选一个数字。以此类推。终止条件是path的长度达到digits的长度。注意题目是给定了digits,不用我们自行生成所有可能的digits

回溯法三部曲
  • 回溯函数参数及返回值

    使用全局变量path收集叶子节点结果,结果数组result保存起来。参数是指定的digits,和index。这个index并非startIndex,而是记录遍历第几个数字。同时index也表示深度。

  • 终止条件

    到达叶子节点,index深度等于数字个数的时候(如果使用这个条件,则index必须从0开始),收集结果,结束本层递归。

  • 回溯搜索的遍历过程

    首先取到index指向的digits中的其中一个数字,然后遍历这个数字对应的字符集,for循环里面添加字符到path,递归,回溯

代码实现

index从1开始的写法

C++
class Solution {
public:
    vector<string> result;
    string path;
    vector<string> lettermap = {"",    "",    "abc",  "def", "ghi",
                                "jkl", "mno", "pqrs", "tuv", "wxyz"};
    void backtracking(string& digits, int index) {
        if (index - 1 == digits.size()) {
            result.push_back(path);
            return;
        }
        int digit = digits[index - 1] - '0';
        string letters = lettermap[digit];
        for (int i = 0; i < letters.size(); i++) {
            path.push_back(letters[i]);
            backtracking(digits, index + 1);
            path.pop_back();
        }
    }
    vector<string> letterCombinations(string digits) {
        result.clear();
        path.clear();
        if (digits.size() == 0)
            return result;
        backtracking(digits, 1);
        return result;
    }
};

index从0开始

C++
class Solution {
private:
    const string letterMap[10] = {
        "", // 0
        "", // 1
        "abc", // 2
        "def", // 3
        "ghi", // 4
        "jkl", // 5
        "mno", // 6
        "pqrs", // 7
        "tuv", // 8
        "wxyz", // 9
    };
public:
    vector<string> result;
    string s;
    void backtracking(const string& digits, int index) {
        if (index == digits.size()) {
            result.push_back(s);
            return;
        }
        int digit = digits[index] - '0';        // 将index指向的数字转为int
        string letters = letterMap[digit];      // 取数字对应的字符集
        for (int i = 0; i < letters.size(); i++) {
            s.push_back(letters[i]);            // 处理
            backtracking(digits, index + 1);    // 递归,注意index+1,一下层要处理下一个数字了
            s.pop_back();                       // 回溯
        }
    }
    vector<string> letterCombinations(string digits) {
        s.clear();
        result.clear();
        if (digits.size() == 0) {
            return result;
        }
        backtracking(digits, 0);
        return result;
    }
};