Letter Combinations of a Phone Number
问题描述:给定包含来自包含数字的字符串2-9,返回该数字可能表示的所有可能的字母组合,下面给出了数字和字母的映射及相应的例子。
- 输入: “23”
- 输出: [“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
这道题一开始我也想不出要用什么方法做,然后就去查找Discuss里面的解法,看到了深度优先搜索(DFS)的方法,才恍然大悟。我们可以想象一下将输入的字符串所映射的字母用树储存起来(从root的子节点开始储存,root不对应任何一个数字),同一层的节点对应一个数字,每一节点的子节点为下一数字对应的字母。从树的root走到其中一个叶节点即为找到的一个字母组合,遍历所有的节点即可找到全部的字母组合。
vector<string> res;
string letter[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
void combination(string digits,string str)
{
//如果字符串为空,代表已经遍历到叶子节点
if(digits.empty())
{
res.push_back(str);
return;
}
string tmp=letter[digits[0]-'0'];
for(int i=0;i<tmp.size();i++)
{
//取digits剩余的部分
combination(digits.substr(1,digits.size()-1),str+tmp[j]);
}
}
vector<string> letterCombinations(string digits)
{
if(digits.empty())
return res;
string str;
combination(digits,str);
return res;
}
Runtime:0ms.
beats 100.00 % of cpp submissions.
在Discuss里面看到了一个非常好的想法,在这里也贴上来分享一下,
vector<string> letterCombinations(string digits) {
vector<string> result;
if(digits.empty()) return vector<string>();
static const vector<string> v = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
result.push_back(""); // add a seed for the initial case
for(int i = 0 ; i < digits.size(); ++i) {
int num = digits[i]-'0';
if(num < 0 || num > 9) break;
const string& candidate = v[num];
if(candidate.empty()) continue;
vector<string> tmp;
for(int j = 0 ; j < candidate.size() ; ++j) {
for(int k = 0 ; k < result.size() ; ++k) {
tmp.push_back(result[k] + candidate[j]);
}
}
result.swap(tmp);
}
return result;
}
这里的swap用得非常好,而且他的想法也非常有趣,有时间来学习一下。