采用的是回溯的思路:
(1)先定义一个哈希表,存储数字与其所代表数的包含字母;定义vector< vector<char> > mychars,其表示目前输入的数字所对应的不同字符组成的二维数组(即每一行是同一数字对应的字符)。
(2)如果输入的数字string长度大于0,则进入dfs,否则直接返回空res。
(3)dfs函数中包含的几个参数:mychars(表示选中的数字所包含的字母组成的二维数组)、 i (表示遍历到了第几个数字)、 j (表示遍历到了当前数字所包含的字母中的第几个)、 s (表示每次函数所加入的字母)。
(4)dfs函数主体思想:
如果dfs函数的 i>=mychars.size(),表示已经遍历完成所有数字,此时的 s 为可选择之一,将其push_back进res;
否则表示还需要继续遍历此时的 i 所代表的数字所包含的字母;
由于同一数字所对应的每个字母都要出现,因此每次都从 k=0 循环到 k<mychars[i].size(), 进入循环后向当前string串中+当前所选定的字符,并且dfs(mychars,i+1,k,s) ,表示遍历下一个数字对应的字母;
下一个字母的遍历结束后,应为还要遍历同行字母对应的下一个字母,所以将当前 s 的值最后一个字母(即遍历前新增上去的)删除,并且将k++(表示遍历同行下一个字母);
最终直至结束。
class Solution {
public:
vector<string> res;
vector<string> letterCombinations(string digits) {
vector< vector<char> > mychars;
string s;
unordered_map<char, string> table{
{'2', "abc"},{'3',"def"}, {'4',"ghi"}, {'5',"jkl"},
{'6',"mno"}, {'7',"pqrs"},{'8',"tuv"},{'9',"wxyz"}};
for( int i=0;i<digits.length() ;i++ ){
vector<char> mychar;
mychar.push_back(table[digits[i]].at(0));
mychar.push_back(table[digits[i]].at(1));
mychar.push_back(table[digits[i]].at(2));
if(table[digits[i]].length()>=4)
mychar.push_back(table[digits[i]].at(3));
mychars.push_back(mychar);
}
if(digits.size()>0) dfs(mychars,0,0,s);
return res;
}
void dfs(vector< vector<char> > mychars,int i,int j,string s){
//i表示遍历到了第几个数字,j表示遍历到了同一个数字的第几个字母
if(i>=mychars.size()){
//每一个数字都已经选择完字母
res.push_back(s);
}
else{
for(int k=0;k<mychars[i].size();k++){
s=s+mychars[i][k];
dfs(mychars,i+1,k,s);
s.erase(s.end()-1);//回退时每一层对不同的同层数进行遍历
}
}
}
};