问题如下。
给定一个数字字符串,返回该数字可能代表的所有可能的字母组合。
下面给出了数字到字母的映射(就像在电话按钮上一样)。
输入:数字字符串" 23"
输出:[" ad"," ae"," af"," bd"," be" ," bf"," cd"," ce"," cf"]。
我使用了回溯,但无法弄清楚为什么回答错误....猜猜我不熟悉递归调用如何处理传递的参数。
有人能帮助我吗?非常感谢! 错误:
class Solution {
public:
const vector<string> keyboard { " ", "", "abc", "def", // '0','1','2',...
"ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
vector<string> letterCombinations(string digits) {
int len =digits.size();
vector<string> res;
string combo;
bt( res, combo,digits, len, 0);
return res;
}
void bt(vector<string> &res, string combo, string digits, int len, int i)
{
if (i==len)
{
res.push_back(combo);
return;
}
int idx = digits[i]-'0';
if (idx<0||idx>9)
return;
string tmp = keyboard[idx];
int s=tmp.size();
for (int j=0; j<s; j++)
{
combo.push_back(tmp[j]);
i++;
bt(res,combo,digits,len,i);
}
}
};
正确:
class Solution {
public:
const vector<string> keyboard { " ", "", "abc", "def", // '0','1','2',...
"ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
vector<string> letterCombinations(string digits) {
int len =digits.size();
vector<string> res;
string combo;
bt( res, combo,digits, len, 0);
return res;
}
void bt(vector<string> &res, string combo, string digits, int len, int i)
{
if (combo.size() == len)
{
res.push_back(combo);
return;
}
int idx = digits[i] - '0';
string tmp = keyboard[idx];
int s = tmp.size();
for (int j = 0; j<s; j++)
{
bt(res, combo + tmp[j], digits, len, i+1);
}
}
};
我后来发现使用BFS对我来说更直观,使我的代码更简洁。或者有什么更好的方法来写这个没有递归?再次感谢你!
class Solution {
public:
const vector<string> keyboard { " ", "", "abc", "def", // '0','1','2',...
"ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
vector<string> letterCombinations(string digits) {
vector<string> res(1, "");
string combo;
int n=digits.size();
vector<string> tmp;
for(int i=0; i<n; i++)
{
int m = keyboard[digits[i]-'0'].size();
int rsize =res.size();
for (int k=0; k<rsize; k++)
{
string ts = res[k];
for (int j=0; j<m; j++)
{
res[k] = res[k] + keyboard[digits[i]-'0'][j];
tmp.push_back(res[k]);
res[k] = ts;
}
}
res = tmp;
tmp.clear();
}
return res;
}
};
答案 0 :(得分:0)
在你的循环中:
for (int j=0; j<s; j++)
{
combo.push_back(tmp[j]);
i++;
bt(res,combo,digits,len,i);
}
让我们说tmp
是"abc"
,当您走过循环时会发生什么?首先,您push_back('a')
并增加i
...然后再添加push_back('b')
并再次增加i
!您需要回溯:
很难:
for (int j=0; j<s; j++)
{
combo.push_back(tmp[j]);
i++;
bt(res,combo,digits,len,i);
combo.erase(i);
--i;
}
更简单的方法:
for (int j=0; j<s; j++)
{
bt(res,combo + tmp[j],digits,len,i + 1);
}
最简单的方法:识别combo.size() == i
是一个不变量并删除一个变量:
for (int j=0; j<s; j++)
{
bt(res,combo + tmp[j],digits,len);
}
这就是&#34;纠正&#34;你发布的解决方案的工作,你没有失败的回溯。
答案 1 :(得分:0)
我在
中看到了问题combo.push_back(TMP [J]);
对于j == 0是正确的,但对于j!= 0是错误的。
例如,如果j == 1.你将输入bt函数combo + tmp [0] + tmp [1]而不是combo + tmp [1]。