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指向的数字转为intstring 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.电话号码的字母组合_哔哩哔哩_bilibili
https://www.bilibili.com/video/BV1yV4y1V7Ug/?spm_id_from=333.788&vd_source=a934d7fc6f47698a29dac90a922ba5a3