一看就是dfs,其实算是比较简单的dfs了,我居然还做不出,我真是个sb。来一个index记录当前遍历到给定字符串的哪一位即可。在dfs里,如果遍历到最后一位了,就将临时字符串加入结果数组。如果没有,就遍历当前字符串中的数字对应的所有的字母,用一个vector来存即可,循环中将tmp+上当前数字的对应字母,然后对其dfs,并将index+1,遍历完后回溯,就是将tmp最后一个字符删掉,用erase(tmp.end()-1)即可,因为end()迭代器是最后一位的后一位,不指向任何字符。
class Solution {
public:
vector<string> vec = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
vector<string> res;
string tmp = "";
void dfs(string digits, int index){
if(index == digits.length()){
res.push_back(tmp);
return;
}
for(int i = 0; i < vec[digits[index]-'0'-2].length();++i){
tmp+=vec[digits[index]-'0'-2][i];
dfs(digits,index+1);
tmp.erase(tmp.end()-1);
}
}
vector<string> letterCombinations(string digits) {
//回溯不是自动回溯就是手动pop,此处是手动pop,难的就是形成树型
//每个按键只能按一次,类似dfs
if(digits.length() == 0) return res;
int index = 0;
dfs(digits,index);//index是记录当前循环到digits的第几位了
return res;
}
};
二刷,当前层只需要考虑把自己这个的数字的字母遍历完就行了,用unordered_map来记录,键值对为char,string,比vector好用多了
class Solution {
public:
//一个index记录遍历到digits的第几位
void dfs(string& digits, int index, string tmp){
if(index == digits.length()){
res.push_back(tmp);
return;
}
//当前层只需要考虑把自己这个的数字的字母遍历完就行了
for(int i = 0; i < ma[digits[index]].length(); ++i){
dfs(digits,index+1,tmp+ma[digits[index]][i]);
}
}
vector<string> letterCombinations(string digits) {
//映射就考虑map,找组合就考虑dfs
//map记录的是字符串,比如ma['2']="abc",也就是回溯
//只要不传引用就不用管回溯之前的pop,如果是全局变量s,要在下一层回来的时候erase(end-1)
if(digits.length() == 0) return res;
string s = "";
dfs(digits,0,s);
return res;
}
private:
unordered_map<char,string> ma{{'2',"abc"},{'3',"def"},{'4',"ghi"},{'5',"jkl"},
{'6',"mno"},{'7',"pqrs"},{'8',"tuv"},{'9',"wxyz"}};
vector<string> res;
};