題目描述:
題解:
一、“平庸”的全排列
思路簡單,直接看代碼。
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;
}
思路比方法一清晰。
複雜度分析:尾遞歸,全排列,複雜度和方法一相同。