题目描述
leetcode_hot100
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
2-abc
3-def
4-ghi
5-jkl
6-mno
7-pqrs
8-tuv
9-wxyz
示例 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’] 的一个数字。
错误示例
思路:一开始只想着暴力循环,但感觉非常不靠谱真的太暴力于是写到第三层就停下来了。
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> com;
if(digits.length()==0){
return com;
}else if(digits.length()==1){
digit2letters(digits[0]);
for(int i=0;i<dig_letrs.length();i++){
com.push_back(dig_letrs[i]);
}
return com;
}else if(digits.length()==2){
digit2letters(digits[0]);
string l1=dig_letrs;
digit2letters(digits[1]);
string l2=dig_letrs;
for(int i=0;i<l1.length();i++){
for(int j=0;j<l2.length();j++){
string group=l1[i]+l2[j];
com.push_back(group);
}
}
return com;
}else if(digits.length()==3){
digit2letters(digits[0]);
string l0=dig_letrs;
digit2letters(digits[1]);
string l1=dig_letrs;
digit2letters(digits[2]);
string l2=dig_letrs;
for(int i=0;i<l0.length();i++){
for(int j=0;j<l1.length();j++){
for(int k=0;k<l2.length();k++){
string group=l0[i]+l1[j]+l2[k];
com.push_back(group);
}
}
}
}
}
private:
string dig_letrs="";
void digit2letters(char d){//找某个数字对应的字母
switch(d){
case '2':
dig_letrs="abc";
break;
case '3':
dig_letrs="def";
break;
case '4':
dig_letrs="ghi";
break;
case '5':
dig_letrs="jkl";
break;
case '6':
dig_letrs="mno";
break;
case '7':
dig_letrs="pqrs";
break;
case '8':
dig_letrs="tuv";
break;
case '9':
dig_letrs="wxyz";
break;
}
}
};
正解
思路:其实最后的结果中每个元素串就是一棵树从根节点到叶子结点的每个路径,使用dfs深度优先算法遍历+递归即可。
class Solution {
public:
vector<string> slist={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
//slist的下标就对应了某几个字母对应的数字
//注意这里不能使用list这种特称
vector<string> res;//用来存放结果
vector<string> letterCombinations(string digits) {
if(digits.length()==0){//没有数字输入时输出空串
return {};
}
dfs("",digits.length()-1,digits);//如果有数字输入,从最后一个数字开始向前遍历,cur_str已有串此时为空
return res;
}
void dfs(string cur_str, int idx,string digits){
if(idx==-1){//当digits从后向前遍历完时,将当前构成的一个串压入res结果容器,跳出递归
res.push_back(cur_str);
return ;
}
if(idx>=0){
int x=digits[idx]-'0';//找到当前digits[idx]字符数字对应的int值作为关键字寻找对应的某几个字母
string tmps=slist[x];//得到该数字对应的某三个/四个字母
for(int i=0;i<tmps.length();i++){//遍历当前数字对应的字母
dfs(tmps[i]+cur_str,idx-1,digits);
//将当前字母接在已有串的前面作为下一轮递归的已有串,跳入下一个数字对应的递归中(即跳入树的下一层)
}
}
}
};
结果:
执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户
内存消耗:6.3 MB, 在所有 C++ 提交中击败了79.05%的用户
通过测试用例:25 / 25