Files
leetcode-master/problems/0017.电话号码的字母组合.md
youngyangyang04 96f7558ab0 Update
2020-08-26 19:00:58 +08:00

2.7 KiB
Raw Blame History

题目地址

https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/

思路

本题要解决如下问题:

  1. 数字和字母如何映射
  2. 两个字母我就两个for循环三个字符我就三个for循环以此类推然后发现代码根本写不出来
  3. 输入1 * #按键等等异常情况

接下来一一解决这几个问题。

  1. 数字和字母如何映射

定义一个二位数组例如string letterMap[10],来做映射

  1. 两个字母我就两个for循环三个字符我就三个for循环以此类推然后发现代码根本写不出来。

遇到这种情况,就应该想到回溯了。

这是一个回溯法的经典题目,不要以为回溯是一个性能很高的算法,回溯其实就是暴力枚举,纯暴力,搜出所有的可能性。

回溯一般都伴随着递归,而这种组合问题,都可以画成一个树形结构。如图所示:

可以想成遍历这棵树,然后把叶子节点都保存下来。

  1. 输入1 * #按键等等异常情况

题目的测试数据中应该没有异常情况的数据,可以不考虑,但是要知道会有这些异常。

那么在来讲一讲回溯法,回溯法的模板如下:

回溯函数() {
    if (终止条件) {
        存放结果;
    }

    for (枚举同一个位置的所有可能性,可以想成节点孩子的数量) {
        递归,处理下一个孩子;
        (递归的下面就是回溯的过程);
    }
}

按照这个模板,不难写出如下代码:

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;
    void getCombinations(const string& digits, int index, const string& s) {
        if (index == digits.size()) {
            result.push_back(s);
            return;
        }
        int digit = digits[index] - '0';
        string letters = letterMap[digit];
        for (int i = 0; i < letters.size(); i++) {
            getCombinations(digits, index + 1, s + letters[i]);
        }
    }
    vector<string> letterCombinations(string digits) {
        if (digits.size() == 0) {
            return result;
        }
        getCombinations(digits, 0, "");
        return result;

    }
};

更多算法干货文章持续更新可以微信搜索「代码随想录」第一时间围观关注后回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等就可以获得我多年整理的学习资料。