一下子看到这个题目并没有什么思路,但是看着好像又有点眼熟,有点类似于全排列的感觉,看了题目解析之后才恍然大悟,这就是我学习过的深度优先搜索算法呀,全排列就可以用这种方法。这个题目的思路整理如下:
1、需要注意的是,当参数string digits的长度为K时,最终子串的长度就是K,这是递归调用的返回条件(也就是相当于完成了一种组合),即当输入"23",长度为2,则结果集中的"ad""ae""af"等长度都是2;
2、基于这个条件,我们对输入的数字串进行递归调用,每次往临时子串变量temp中,添加当前数字对应的字串中的一个字母,并且每当完成一组子串后,将其添加到结果集的同时,将临时变量temp弹出上一个字符,深度优先搜索;
说明一下深度优先搜索的意义:深度优先搜索的关键在于“当下该如何做”,至于“下一步如何做”则与“当下该如何做”是一样的。在这个题目中也是一样的,遇到第一个数字的时候应该for循环一下把每一种可能都尝试一遍,当前这一步解决之后就进入下一步,也就是遇到第二个数字的时候,这一步的解决方法和上一步的解决方法是完全一样的,下面是深度优先搜索的基本模型:
void dfs(参数){
判断边界;
尝试每一种可能 for(i=1;i<n;i++){
继续下一步 dfs(相同的参数);
}
返回
}
参考代码:
class Solution{
public:
vector<string> letterCombinations(string digits){
vector<string> result;
string temp = "";
if(digits.size() < 1)
return result;
map<char,string>myMap;
myMap['2'] = "abc";
myMap['3'] = "def";
myMap['4'] = "ghi";
myMap['5'] = "jkl";
myMap['6'] = "mno";
myMap['7'] = "pqrs";
myMap['8'] = "tuv";
myMap['9'] = "wxyz";
MyFunc(digits, temp, result, myMap);
return result;
}
private:
void MyFunc(string digits, string temp, vector<string>& result, map<char, string>myMap){
int currLen = temp.size();
if(currLen == digits.size()){
result.push_back(temp);
}
else{
for(int i = 0; i < myMap[digits[currLen]].size(); i++){
temp = temp + myMap[digits[currLen]][i];
MyFunc(digits, temp, result, myMap);
temp.pop_back();
}
}
}
};