目录
给定一个仅包含数字 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'] 的一个数字。
一开始,按照传统思路,我给它来了一个四层循环,外两层循环变换字符串,内两层循环拼接字符串,然后本地可以出结果,leetcode上就运行超时。然后就只能用算法解决了。
- class Solution {
- public:
- vector
letterCombinations(string digits) { - string code[8] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}, temp;
- vector
answer,topick; - for(auto & it:digits)topick.push_back(code[it-'2']);
- for(int i=0;i
size()-1;i++) - for(int j=i+1;j
size();j++) - for(auto & it:topick[i])
- for(auto & itit:topick[j]){
- temp.clear();
- temp.insert(temp.end(),it);
- temp.insert(temp.end(),itit);
- answer.push_back(temp);
- }
- return answer;
- }
- };
类似与树和图的结构;请看图片:
如果不用算法,暴力解决的话,理论上有几个字符串,就需要几个循环嵌套。
所以我们可以用深度优先的回溯来解决这个问题,详情看代码注释。
- class Solution {
- public:
- string code[8] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};//设置为类数据,方便调用,不需要传太多参数
- vector<string>answer;
- string digit;//方便调用,不需要传参数
- void backtrack(string temp,int depth) {
- if(depth==digit.size())answer.push_back(temp);//如果层数与数字的个数,即总字符串数相同,说明这一枝拼接完毕
- else{
- string temptemp=code[digit[depth]-'2'];//提取数字对应的字符串
- for(auto it:temptemp)backtrack(temp+it,depth+1);//对于每一个子节点,拼接下一层
- }
- }
- vector<string> letterCombinations(string digits) {
- digit=digits;//拷贝一份digits
- if(digit.size()==0)return {};//空输入返回空字符串
- backtrack("",0);//调用
- return answer;
- }
- };