17. 电话号码的字母组合 - 力扣(LeetCode)
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = ""
输出:[]
示例 3:
输入:digits = "2"
输出:["a","b","c"]
本题需要解决三个问题,思考和分析:
- (1)数字和字母集合如何做映射
- (2)两个字母就需要两个for循环,那很多个字母岂不是要很多层for循环嵌套,怎么解决?、
- (3)输入1 * #按键等等异常情况
解决思路:1.创建字符集(使数字和字母集做映射)
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
2.回溯算法来解决 n 个 for 循环的问题,举个栗子:输入"23",长度为 2
- 回溯可以通过递归的方式来帮我们去实现嵌套几个for循环
- 输入"23" 的长度为 2,正是树的深度
- 叶子节点要收集的结果,输出["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
>>回溯三部曲:
1).确定回溯函数参数
- 字符串 strPath 来收集叶子节点的结果
- result 保存 strPath,作为结果集
- index 是记录遍历第几个数字了,同时 index 也表示树的深度
vector<string> result;
string strPath;
void backtracking(const string& digits, int index)
2).确定终止条件
- 如果 index 等于 输入的数字个数(digits.size)了,就终止,这是因为 index 就是用来遍历digits 的
- 举个栗子:"23",有两个数字,那么根节点往下递归两层就可以了
- 收集结果,结束本层递归
if(index == digits.size()) {
result.push_back(strPath);
return;
}
3).确定单层遍历逻辑
- 先取出 index 在 digits 中的数字,再取找出对应的字符集
- 接着 for 循环处理这个字符集
int num = digits[index]-'0';// 将index指向的数字转为int
string charSet = letterMap[num];// 取数字对应的字符集
for(int i=0;i<charSet.size();i++) {
strPath.push_back(charSet[i]);// 处理
backtracking(digits,index+1);// 递归,注意index+1,一下层要处理下一个数字了
strPath.pop_back();// 回溯
}
C++ 代码:
class Solution {
public:
vector<string> result;
string strPath;
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
void backtracking(const string& digits,int index) {
if(index == digits.size()) {
result.push_back(strPath);
return;
}
int num = digits[index]-'0';// 将index指向的数字转为int
string charSet = letterMap[num];// 取数字对应的字符集
for(int i=0;i<charSet.size();i++) {
strPath.push_back(charSet[i]);// 处理
backtracking(digits,index+1);// 递归,注意index+1,一下层要处理下一个数字了
strPath.pop_back();// 回溯
}
}
vector<string> letterCombinations(string digits) {
if (digits.size() == 0) return result;
backtracking(digits,0);
return result;
}
};
参考和推荐文章,视频:
代码随想录 (programmercarl.com)https://www.programmercarl.com/0017.%E7%94%B5%E8%AF%9D%E5%8F%B7%E7%A0%81%E7%9A%84%E5%AD%97%E6%AF%8D%E7%BB%84%E5%90%88.html#%E6%80%9D%E8%B7%AF还得用回溯算法!| LeetCode:17.电话号码的字母组合_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1yV4y1V7Ug/?spm_id_from=333.788&vd_source=a934d7fc6f47698a29dac90a922ba5a3