mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-08-06 18:24:23 +08:00
2.8 KiB
2.8 KiB
题目地址
https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
思路
本题要解决如下问题:
- 数字和字母如何映射
- 两个字母我就两个for循环,三个字符我就三个for循环,以此类推,然后发现代码根本写不出来
- 输入1 * #按键等等异常情况
接下来一一解决这几个问题。
- 数字和字母如何映射
定义一个二位数组,例如:string letterMap[10],来做映射
- 两个字母我就两个for循环,三个字符我就三个for循环,以此类推,然后发现代码根本写不出来。
遇到这种情况,就应该想到回溯了。
这是一个回溯法的经典题目,不要以为回溯是一个性能很高的算法,回溯其实就是暴力枚举,纯暴力,搜出所有的可能性。
回溯一般都伴随着递归,而这种组合问题,都可以画成一个树形结构。
例如:输入:"23",如图所示:
可以想成遍历这棵树,然后把叶子节点都保存下来,输出["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]。
- 输入1 * #按键等等异常情况
题目的测试数据中应该没有异常情况的数据,可以不考虑,但是要知道会有这些异常。
那么在来讲一讲回溯法,回溯法的模板如下:
backtracking() {
if (终止条件) {
存放结果;
}
for (枚举同一个位置的所有可能性,可以想成节点孩子的数量) {
递归,处理节点;
backtracking();
回溯,撤销处理结果
}
}
按照这个模板,不难写出如下代码:
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」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。