https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/
自己写的:
class Solution {
public:
vector<string> letterCombinations(string digits) {
string digitsNew = "";
for (int i = 0; i < digits.size(); ++i)
{
if (digits[i] <= '9' && digits[i] >= '2')
{
digitsNew.append(1, digits[i]);
}
}
vector<string> ret;
if (digitsNew.size() >= 1)
{
ret = letterCombinationsHelper(digitsNew, 0, digitsNew.size() - 1);
}
return ret;
}
Solution()
{
string Letters[] = { "abc", "def","ghi","jkl","mno","pqrs","tuv","wxyz" };
m_digitToLetter = vector<string>(Letters, Letters + sizeof(Letters) / sizeof(string));
}
private:
vector<string> letterCombinationsHelper(string digitsNew, int first, int last)
{
vector<string> ret;
if (first == last)
{
string curStr = m_digitToLetter[digitsNew[first] - '2'];
for (int i = 0; i < curStr.size(); ++i)
{
ret.push_back(string(1, curStr[i]));
}
}
else
{
vector<string> oldRet = letterCombinationsHelper(digitsNew, first, last - 1);
string lastStr = m_digitToLetter[digitsNew[last] - '2'];
for (int j = 0; j < oldRet.size(); ++j)
{
for (int i = 0; i < lastStr.size(); ++i)
{
string cur = oldRet[j];
ret.push_back(cur.append(1, lastStr[i]));
}
}
}
return ret;
}
vector<string> m_digitToLetter;
};
注意点:
1. append形参顺序,先个数,再字符。
cur.append(1, lastStr[i])
2.使用数组进行初始化vector,形参,start 和 end迭代器。
m_digitToLetter = vector<string>(Letters, Letters + sizeof(Letters) / sizeof(string));
leetcode上的示例:
class Solution {
public:
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;
}
};
分析:
1.调用内置函数,而不用size来做判断
digits.empty()
2.使用静态局部变量,避免每一次都初始化。0和1对应的字符串设置为空,映射关系更加直观。
static const vector<string> v = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
3.一开始就转化为数字。(自己之前有bug,直接digits[i]-0;)
int num = digits[i]-'0';
4.调用string的operator+(const string&, char n)来进行拼接字符串。(盲点,不知道有这个函数)
tmp.push_back(result[k] + candidate[j]);
5.关键思想,两个vector,一个存已经生成的(种子),一个存新生成的(用种子 拼接 新字符)。然后互换。
result.swap(tmp);
6.不存在递归
一点小tip:
int main() {
string as0 = "ab" + 'b'; // char* 指针 + 'b'的asc码
// string as1 = "ab" + "b"; // 编译错误 :不能将两个指针相加
string ab("ab");
string as2 = ab + 'b'; // 正确的连接效果 abb
return 0;
}