给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:"23" 输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
思路一:采用递归的方法,每次传入当前遍历的字符串curStr和计数器curCount,如果curCount==nums.size(),那把curStr加入res中,否则就继续递归调用自身,注意当前的curStr加入新的字符在调用完递归函数以后要pop一下,否则curStr会不断累加。
参考代码:
class Solution {
public:
string IntToString(int curN) {
string res;
if ((curN >= 2 && curN <= 6)) {
for (int i = (curN - 2) * 3; i < (curN - 2) * 3 + 3; i++) {
res.push_back((char)('a' + i));
}
}
else if(curN==7){
for (int i = 0; i < 4; i++) {
res.push_back((char)('p' + i));
}
}
else if (curN == 8) {
for (int i = 0; i < 3; i++) {
res.push_back((char)('t' + i));
}
}
else if (curN == 9) {
for (int i = 0; i < 4; i++) {
res.push_back((char)('w' + i));
}
}
return res;
}
void letterCombinationsCore(string &digits, int curIndex, vector<string> &res, string &curStr) {
if (curIndex == digits.size()) {
res.push_back(curStr);
return;
}
for (int i = 0; i < IntToString(digits[curIndex] - '0').size(); i++) {
curStr.push_back(IntToString(digits[curIndex] - '0')[i]);
letterCombinationsCore(digits, curIndex + 1, res, curStr);
curStr.pop_back();
}
}
vector<string> letterCombinations(string digits) {
vector<string> res;
if (digits.empty() || digits.size() == 0) return res;
string curStr;
letterCombinationsCore(digits, 0, res, curStr);
return res;
}
};
思路二:采用循环的方法,相当于为了避免爆栈的问题,每次都选出候选的字符,然后对于每个字符都遍历一遍res,加到res中。最后返回res。
比如我们输入“234”,那么每次考察的都是当前res和候选集的字符,每次把候选集的字符加到res中。
Explanation with sample input "234"
Initial state:
- result = {""}
Stage 1 for number "1":
- result has {""}
- candiate is "abc"
- generate three strings "" + "a", ""+"b", ""+"c" and put into tmp,
tmp = {"a", "b","c"} - swap result and tmp (swap does not take memory copy)
- Now result has {"a", "b", "c"}
Stage 2 for number "2":
- result has {"a", "b", "c"}
- candidate is "def"
- generate nine strings and put into tmp,
"a" + "d", "a"+"e", "a"+"f",
"b" + "d", "b"+"e", "b"+"f",
"c" + "d", "c"+"e", "c"+"f" - so tmp has {"ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf" }
- swap result and tmp
- Now result has {"ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf" }
Stage 3 for number "3":
- result has {"ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf" }
- candidate is "ghi"
- generate 27 strings and put into tmp,
- add "g" for each of "ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"
- add "h" for each of "ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"
- add "h" for each of "ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"
- so, tmp has
{"adg", "aeg", "afg", "bdg", "beg", "bfg", "cdg", "ceg", "cfg"
"adh", "aeh", "afh", "bdh", "beh", "bfh", "cdh", "ceh", "cfh"
"adi", "aei", "afi", "bdi", "bei", "bfi", "cdi", "cei", "cfi" } - swap result and tmp
- Now result has
{"adg", "aeg", "afg", "bdg", "beg", "bfg", "cdg", "ceg", "cfg"
"adh", "aeh", "afh", "bdh", "beh", "bfh", "cdh", "ceh", "cfh"
"adi", "aei", "afi", "bdi", "bei", "bfi", "cdi", "cei", "cfi" }
Finally, return result.
参考代码:
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> res;
if (digits.empty()) return res;
vector<string> map = { "","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz" };
res.push_back("");
for (int i = 0; i < digits.size(); i++) {
string newChars = map[digits[i] - '0'];
vector<string> tmp;
for (int i = 0; i < newChars.size(); i++) {
for (int j = 0; j < res.size(); j++) {
tmp.push_back(res[j] + newChars[i]);
}
}
res.swap(tmp);
}
return res;
}
};