题目描述:
题解:
一、“平庸”的全排列
思路简单,直接看代码。
vector<string> letterCombinations(string digits) {
if (digits.empty())return{};
vector<string> key_map{ "abc","def","ghi","jkl","mno","pqrs","tuv","wxyz" };
vector<string> rst{};
for (char i : key_map[digits[0] - '2']) {
rst.push_back(string{ i });
}
for (int i = 1; i < digits.size(); i++) {
vector<string> temp_v_s{};
for (char c : key_map[digits[i] - '2']) {
for (string s : rst) {
temp_v_s.push_back(s + string{ c });
}
}
rst = temp_v_s;
}
return rst;
}
这里需要提到的是,一个月前做这道题提交结果,现在回头整理再提交同样的代码时,两次运行时间和内存占用大相径庭。貌似leetcode的提交结果不太具有参考价值,还是从算法复杂度来比较吧。
复杂度分析:时间复杂度:O(3N*4M),其中 N 是输入数字中对应3个字母的数目(比如2,3,4,5,6,8), M 是输入数字中对应4个字母的数目(比如7,9),N+M是输入数字的的总个数。
空间复杂度:O(3N*4M),需要保存3N*4M个结果。
二、递归解法
map<char, string> key_map = {
{ '2',"abc" },
{ '3',"def" },
{ '4',"ghi" },
{ '5',"jkl" },
{ '6',"mno" },
{ '7',"pqrs" },
{ '8',"tuv" },
{ '9',"wxyz" }
};
vector<string> rst{};
void backtrack(string combination, string next_digits) {
if (next_digits.empty()) {
rst.push_back(combination);
}
else {
char digit = next_digits[0];
string letters = key_map[digit];
for (int i = 0; i < letters.size(); i++) {
string letter = letters.substr(i, 1);
backtrack(combination + letter, next_digits.substr(1));
}
}
}
vector<string> letterCombinations(string digits) {
if (!digits.empty())
backtrack("", digits);
return rst;
}
思路比方法一清晰。
复杂度分析:尾递归,全排列,复杂度和方法一相同。