描述
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
思路
这道题不太难,因为不需要考虑不合法的情况。这道题类似于数学中的全排列问题,输入有几个字符,也就是按了几下键盘,结果中的每个字符串就多长。最终的结果是字符0对应的字母长度乘上字符1对应的字母长度乘上字符2对应的…即:按了234三个键,每个键对应3个字母,最终有3x3x3种结果。这是一个深度优先遍历的过程。
-
首先建立一个map,保存每个数字代表的字符串。程序开始时,先将输入的按键对应的字符串提取出来,放到一个vector中,即下面的v,有几个按键,vector的长度就是多少。
-
递归开始时,先从vector[0]开始,即第一个按键,一直遍历到最后一个按键。每次都遍历每一个按键的代表的每一个字母,并将其添加到字符串tmp_s中。
-
递归的出口是:当字符串的长度等于输入的按键数时。
解答
class Solution {
public:
vector<string> res;
vector<string> v;//暂时存储输入的数字对应的字符串
string tmp_s;//暂时存储字符串
int N;
map<char, string> m = {{'2',"abc"},
{'3', "def"},
{'4', "ghi"},
{'5', "jkl"},
{'6', "mno"},
{'7', "pqrs"},
{'8', "tuv"},
{'9', "wxyz"}
};
vector<string> letterCombinations(string digits) {
N = digits.size();
if(N == 0) return res;
for(int i = 0;i < N; ++i){
v.push_back(m[digits[i]]);
}
backTrack(0);
return res;
}
//count从0开始递增到输入的字符长度,每个字符代表的按键字母存在v[count]中
void backTrack(int count){
if(tmp_s.size() == N){//递归出口
res.push_back(tmp_s);
return;
}
for(int i = 0;i < v[count].size(); ++ i){
tmp_s.push_back(v[count][i]);
backTrack(count + 1);
tmp_s.pop_back();
}
}
};