题意理解
输入2到9数组组成的字符串,长度不限,每个数字对应几个字母,问不同的数字串对应的字母串的情况
问题分析
用回溯法。
设计回溯函数,状态空间是
基本项是数字串为空,字母串为空
归纳项是前i个字符,前i-1个字符的字母串列表加上最后一个字符的对应的字母
其他
递归设计要点,写出递归定义,由基本项和归纳项两部分组成
基本项描述了一个或几个递归过程的终结状态;
归纳项描述了如何实现从当前状态到终结状态的转化。
回溯法的函数生成有点复杂。https://leetcode.com/articles/letter-combinations-of-a-phone-number/
链接
vector<string> letterCombinations(string digits) {
map<string,string> dicts;
dicts["2"] = "abc";
dicts["3"] = "def";
dicts["4"] = "ghi";
dicts["5"] = "jkl";
dicts["6"] = "mno";
dicts["7"] = "pqrs";
dicts["8"] = "tuv";
dicts["9"] = "wxyz";
vector<string> results;
if (digits.size() == 0) //如果数字串为空
return results; //结果为空
results = backtrack("", dicts, digits);
return results;
}
vector<string> backtrack(string combination, map<string,string> dicts, string next_digits) //参数1表示解的一部分,参数2,参数3辅助生成完全解
{
//cout << combination << '\t' << next_digits << endl;
vector<string> results;
if (next_digits.size() == 0) //判断解是不是完全,用剩余数字是不是存在
{
results.push_back(combination); //部分解就是完全解,直接放入最后结果。
return results;
}
else //不是完全解
{
string digit = next_digits.substr(0, 1); //进一步生成完全解,剥离剩余数字第一个数字
string letters = dicts[digit]; //产生数字的字母串
for(int i = 0; i < letters.size(); i++) //遍历字母串
{
string letter = letters.substr(i, 1);
vector<string> newCombination = backtrack(combination + letter, dicts, next_digits.substr(1, next_digits.size() - 1)); //部分解进化,辅助参数缩小范围
results.insert(results.begin(), newCombination.begin(), newCombination.end()); //将生成的完全解序列插入最后结果
}
return results;
}
}