题目
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = ""
输出:[]
示例 3:
输入:digits = "2"
输出:["a","b","c"]
提示:
0 <= digits.length <= 4
digits[i]
是范围['2', '9']
的一个数字。
解答
- 回溯法
理解本题后,要解决如下三个问题:
- 数字和字母如何映射?使用二维数组即可。
- 两个字母就两个for循环,三个字符我就三个for循环,以此类推,然后发现代码根本写不出来,此时的思路就是使用增加了遍历深度的参数的辅助函数进行辅助,得到一种符合要求的结果后进行回溯继续遍历。
- 输入1 * #按键等等异常情况(异常情况在leetcode样例中不存在,所以不考虑也没关系)
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; // 用于存储最终结果的全局变量动态数组result
string s; // 用于临时存储一个组合的字符串s
void backtracking(const string& digits, int index) {
// 辅助函数,增加了一个index用于辅助遍历的过程,index表示遍历到digits的第几位
if (index == digits.size()) {
// 判断index是否和digits的大小相等,如果相等则说明当前已经遍历完了最后一位
result.push_back(s); // 此时直接把保存的字符串s放进结果数组result中即可
return; // 遍历结束直接return
}
int digit = digits[index] - '0'; // 把字符串中的单个数字转为int类型
string letters = letterMap[digit]; // 通过获得的int类型数字得到对应的字符串映射
for (int i = 0; i < letters.size(); i++) {
s.push_back(letters[i]); // 将第i个字母进行push
backtracking(digits, index + 1); // 递归进一步遍历
s.pop_back(); // 回溯
}
}
vector<string> letterCombinations(string digits) {
s.clear(); // 初始化参数
result.clear(); // 初始化参数
if (digits.size() == 0) return result; // 如果digits数组的长度为0 直接返回空结果数组
backtracking(digits, 0); // 递归调用,从0开始遍历
return result; // 返回最终的结果数组
}
};