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; }