题目描述
思路分析
迭代法(或者叫做宽度有限搜索)
最外层循环遍历给定的源串,比如"234",比如遍历到第一个字符2,对应的字符串为"abc"
进入第二层循环,先得出当前已得到的res的长度,这一步最关键,详细说明如下:
设定一个变量vector res{""}用来存储最终的结果;初始为空字符串,很关键,这样在遍历第一个字符2的时候,会将2对应的每一个子串写入到res中,此时res为{"a","b","c"}。当继续遍历第二个字符3的时候,先求得res的长度为3,这样可以遍历到每一个子串"a", "b", "c",然后拿每一个子串去与当前的3对应"def"依次相加(这是第三层循环),得到新的子串集合,{"ad","ae","af","bd","be","bf","cd","ce","cf"},即为更新之后的res。后面的以此类推。
迭代法代码实现
class Solution {
public:
vector<string> letterCombinations(string digits) {
if (digits.empty()) {
return vector<string>{};
}
vector<string> dict {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
vector<string> res {""}; // 最开始设为只有一个空字符串的集合
for (int i = 0; i < digits.size(); i++) {
string cur_str = dict[digits[i] - '0']; // 比如"abc"
vector<string> res2; // 为了重新求得一个字符串集合,再替换原来的字符串集合
for (int j = 0; j < res.size(); j++) {
string tmp = res[j];
for (int k = 0; k < cur_str.size(); k++) {
res2.push_back(tmp + string(1, cur_str[k]));
}
}
res = res2;
}
return res;
}
};
深度优先搜索法
顾名思义,深度优先即,比如digits为"234",2->"abc", 3->"def", 4->"ghi",则深度搜索会先得到adg,adh,adi,然后得到aeg,aeh,aei也就是先以最后一个数字对应的字符完整遍历一遍,与上面的思路相反。
最核心的地方在于DFS函数的中止条件 level == digits.size() 这表示一次遍历的结束,得到了一个完整的结果集中的一个子串,然后进入下一次遍历。具体参考代码注释。
深度优先代码实现
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> res;
if (digits.empty()) return res;
string dict[] = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
DFS(digits,dict,0,"",res);
return res;
}
// 参数digits为源串,disc为对应的字典,level即为当前走到的数字的index,out为当前已累积的子串,res为最终结果
void DFS(string digits, string dict[], int level, string out, vector<string>& res){
// 走到这里说明一次遍历结束,比如源串为"234",则走到了4对应的字符"ghi"中的某一个,函数返回,继续遍历ghi中的
// 下一个字符
if (level == digits.size()) {
res.push_back(out);
return;
} else {
//找到当前的数字(2~9)对应的stirng("abc"~"wxyz")
string str = dict[digits[level]-'2'];
for (int i = 0; i < str.size(); i++)
{
// 假设源串为"234",且当前走到了4,且i为0,即str[i]为g,此时out为"adg",于是进入DFS函数,
// 因为level==digits.size(),res 添加了一个adg,然后执行out.pop_back(),这时候out为"ad"
// 当i为1时,out变为"adh",然后DFS又返回,使得res添加一个adh,然后执行out.pop_back(),这时候
// out变为"ad",然后i为2时。。。
out.push_back(str[i]);
DFS(digits, dict, level+1, out, res);
out.pop_back();
}
}
}
};