17. Letter Combinations of a Phone Number
Given a digit string, return all possible letter combinations that the number could represent.
![]()
A mapping of digit to letters (just like on the telephone buttons) is given below.Input:Digit string “23”
Output: [“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.
题意
给定一个数字字符串,返回所有数字代表的字符组成的字符串
注意
边界:字符串的合法性
数字1,*号,#号如何处理 该题不给予考虑。
空数字字符串的输入
多个解的顺序
思路
典型的树形问题。
数字字符串的个数代表树的高度。e.g digits=”23”
digits 是数字字符串
s(digits) 是digits所能代表的字母字符串
s(digits[0…n-1])
= letter(digits[0]) + s(digits[1…n-1])
= letter(digits[0]) + letter(digits[1]) + s(digits[2…n-1])
= ……
- 从2开始有三条路,到3也有三条路,选择a路线,输出为ad,回溯到3,输出为ae,回溯到3,输出为af,继续向上一层回溯2,走b路线。。。
- 提前将数字和字符间的映射关系存储好
- 假设所有的数字代表三个字符那么时间复杂度为O(3^n) =O(2^n),n为数字字符串的长度,一般计算机处理大概到20。
- 回溯法是暴力解法的一个主要实现手段
- 当数字字符串长度是固定的可以使用多重循环迭代解决。此题n是一个不确定的,只能使用递归
代码
class Solution {
private:
vector<string> record = { " ", "", "abc", "def", "ghi",
"jkl", "mno", "pqrs", "tuv", "wxyz" };
vector<string> res1;
// p中保存了此时从digits[0...index-1]翻译得到的一个字母字符串
// 寻找和digits[index]匹配的字母, 获得digits[0...index]翻译得到的解
void addletters(string digits, int index, string p)
{
//cout << index << " : " << p << endl; //调试
//index可以看做树的层数
if (index == digits.size()) //digits当前的索引index到达digits的末尾开始回溯,表示已经到底部
{
//保存一种结果,并返回到上一层
res1.push_back(p);
return;
}
char c = digits[index];
string letters = record[c-'0'];
for (int i = 0; i < letters.size(); i++) //当前层字符的个数
{
//cout << "digits[" << index << "] = " << digits[index] << " , use " << record[digits[index] - '0'][i] << endl;
//注意:digits内存储的是string类型,取出来的也是字符,比如:'2'对其取vector下标将是ASCII码,所以应该转化为数字
addletters(digits, index + 1, p + letters[i]);
}
return;
}
public:
vector<string> letterCombinations(string digits) {
if(digits == "") //字符串应该判断为空,而不是NULL
{
return res1;
}
addletters(digits, 0, "");
return res1;
}
};