0
点赞
收藏
分享

微信扫一扫

leetcode 17. 电话号码的字母组合 思考分析

题目

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
leetcode 17. 电话号码的字母组合 思考分析_leetcode

思考与递归程序

解空间树的宽度是输入数字对应的字符的个数,深度是输入的数字的个数。
确定回溯函数参数
与之前​leetcode 216. 组合总和 III 思考分析​一样,我们需要建立两个全局变量,一个存放叶子结点子结果,一个用来存放所有子结果。
参数:第一个是string digits(数字字符串),一个是int index.
用index记录遍历第几个数字了。

vector<string> result;
string res;
void backtracking(const string& digits,int index)

确定终止条件
当index等于数字个数时收集结果,返回。

if(index == digits.size())
{
result.push_back(s);
return;
}

单层逻辑
取第index个数字,并且找到对应的字符集。然后for循环这个字符集(for循环处理的是当层的树宽度有关数据)
同时注意原来的字符类型的数字,要进行转换。

int digit = digits[index]-'0';
string letters = letterMap[digit]; //取出对应的字符集
for(int i=0;i<letters.size();i++)
{
res.push_back(letters[i]);
backtracking(digits,index+1);
res.pop_back(); //回溯
}

异常输入情况输入处理
如果输入1、*、#等字符时,我们应该返回并且打印出错误信息

//判断是否有非法字符
if(digits[index]=='0' || digits[index]=='1'|| digits[index]=='*'|| isValid == false)
{
isValid=false;
result.clear();
//res.clear(); 如果这里clear的话,返回到上一层的时候,会有个回溯操作res.pop,会导致报错
return;
}

完整代码:

class Solution {
public:
const string letterMap[10]={
"", //0
"", //1
"abc", //2
"def", //3
"ghi", //4
"jkl", //5
"mno", //6
"pqrs", //7
"tuv", //8
"wxyz", //9
};
vector<string> result;
string res;
bool isValid =true;
void backtracking(const string& digits,int index)
{
if(index == digits.size())
{
result.push_back(res);
return;
}
//判断是否有非法字符
if(digits[index]=='0' || digits[index]=='1'|| digits[index]=='*'|| isValid == false)
{
isValid=false;
result.clear();
//res.clear();
return;
}
int digit = digits[index]-'0';
string letters = letterMap[digit]; //取出对应的字符集
for(int i=0;i<letters.size();i++)
{
res.push_back(letters[i]);
backtracking(digits,index+1);
res.pop_back(); //回溯
}
}
vector<string> letterCombinations(string digits) {
result.clear();
res.clear();
isValid = true;
if(digits.size() == 0) return result;
backtracking(digits,0);
if(isValid == false) cout<<"输入的字符中有异常"<<endl;
return result;
}
};

对错误案例的测试:
很显然,力扣的测试程序中并没有考虑异常输入
leetcode 17. 电话号码的字母组合 思考分析_数据结构_02
leetcode 17. 电话号码的字母组合 思考分析_数据结构_03

语法细节

1、函数传参中
直接用string s相当于是拷贝了一份,而用&不用拷贝内存。
2、在函数中如果用不带const的引用会报错:
临时变量不能作为非const的引用参数,换句话说就是要引用临时变量必须带上const,这是c++的语法规范。
函数参数作为引用,函数就有责任把函数内存操作此参数的结果给出来。但是这个是一个临时变量,随时可能释放掉。所以为了避免这个现象,就加上一个规则,不带const的临时变量不让通过。


举报

相关推荐

0 条评论