1.题目链接:
17. 电话号码的字母组合
2.解题思路:
2.1.题目要求:
给定一个仅包含数字 2-9
的字符串 digits ,返回所有它能表示的字母组合。
数字和字母的关系:
例子:
输入:"23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
2.2.思路:
制作成n叉树,比如下图,输入"23",遍历完 2 的字母然后又遍历 3的字母。
2.3.回溯三部曲:
先用二维数组映射数字和字母的关系
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
2.3.1.确定回溯函数参数
首先需要一个字符串s来收集叶子节点的结果,然后用一个字符串数组result保存起来,这两个定义为全局变量,可以显的参数简洁一点。
函数的参数写题目传进来的数字字符串 digits ,以及int型的index(代表遍历的层数)
index用于终止条件,作用是统计数字数量,用于终止条件(下面解释)
vector<string> result;
string s;
void backtracking(const string& digits, int index)
2.3.2.确定终止条件
终止条件就是当 输入的数字个数(digits.size) 等于 index 遍历的层数后,把字符串 s 搜集到的结果,传入结果集 result。
if (index == digits.size()) {
result.push_back(s);
return;
}
2.3.3.确定单层遍历逻辑
先将 字符串digits 里的"数字"转成int类型的数字,因为题目给的数字实际上是字符串...需要先进行转化,
用这个数字取上面定义的数字和字母的映射,取出数字对应的字母集,用于for循环(for循环里在按顺序取出字母进行配对)
int digit = digits[index] - '0'; // 将index指向的数字转为int
string letters = letterMap[digit]; // 取数字对应的字符集
后面就是for循环了,遍历的结果输入储存字符串 s 里面,用于在终止条件触发的时候,输入结果集,同时记得要回溯。
for (int i = 0; i < letters.size(); i++) {
s.push_back(letters[i]); // 处理
backtracking(digits, index + 1); // 递归,注意index+1,一下层要处理下一个数字了
s.pop_back(); // 回溯
}
组合一下:
int digit = digits[index] - '0'; // 将index指向的数字转为int
string letters = letterMap[digit]; // 取数字对应的字符集
for (int i = 0; i < letters.size(); i++) {
s.push_back(letters[i]); // 处理
backtracking(digits, index + 1); // 递归,注意index+1,一下层要处理下一个数字了
s.pop_back(); // 回溯
}
2.4.总代码:
// 版本一
class Solution {
private:
const string letterMap[10] = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
public:
vector<string> result;
string s;
void backtracking(const string& digits, int index) {
if (index == digits.size()) {
result.push_back(s);
return;
}
int digit = digits[index] - '0'; // 将index指向的数字转为int
string letters = letterMap[digit]; // 取数字对应的字符集
for (int i = 0; i < letters.size(); i++) {
s.push_back(letters[i]); // 处理
backtracking(digits, index + 1); // 递归,注意index+1,一下层要处理下一个数字了
s.pop_back(); // 回溯
}
}
vector<string> letterCombinations(string digits) {
s.clear();
result.clear();
if (digits.size() == 0) {
return result;
}
backtracking(digits, 0);
return result;
}
};
3.疑问
字符串类型减个字符型的 '0' 就变成int类型的了??
int digit = digits[index] - '0';
C++中用数字表示的字符减去字符 '0'的含义是讲该char类型的字符转换为对应的int类型,
例如;
-
char S = '5';
-
int X = S - '0';
-
cout << X << endl;
X的输出结果是:
x:5
index初始值干嘛要取个0?他是干嘛的??
好像他是层数,用于在终止条件上作比较的,加入数字数量是2,初始是0层,递归一次=1,第二次变成=2,这个时候要进行第三次了。在第三次的递归里碰上终止条件,然后返回,嗯,刚好也可以。
4.记录:
无,待会写下代码,
太晚了,没梳理完,代码也只是过,不过进度要紧。也没有那么多完美的事,尽力完善就好