leetcode:17. 电话号码的字母组合
题目
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
输入:digits = ""
输出:[]
输入:digits = "2"
输出:["a","b","c"]
提示:
0 <= digits.length <= 4
digits[i]
是范围['2', '9']
的一个数字。
解答 & 代码
递归回溯:
class Solution {
private:
// 存储每个数字可能对应的字母, eg. phoneMap[2]="abc",代表数字2可能对应字母a、b、c
vector<string> phoneMap = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
vector<string> resultList; // 结果数组
string result; // 一种可能的排列组合
// 递归回溯
void backTrack(string digits, int idx)
{
// 递归结束条件:如果当前遍历 digits 结束(idx 越界),则将当前的字母组合 result 存入 resultList
if(idx >= digits.size())
{
resultList.push_back(result);
return;
}
int digit = digits[idx] - '0'; // 当前遍历到的数字
string candidates = phoneMap[digit]; // 当前数字对应的所有候选字母
// 遍历所有当前数字的所有候选字母
for(int i = 0; i < candidates.size(); ++i)
{
result.push_back(candidates[i]); // 将该字母插入 result 尾部
backTrack(digits, idx + 1); // 递归处理下一个数字
result.pop_back(); // 回溯,撤销改动
}
}
public:
vector<string> letterCombinations(string digits) {
if(digits.size() > 0)
backTrack(digits, 0);
return resultList;
}
};
复杂度分析:设电话号码共有 n 个数字(其中 i 个数字对应 3 个字符,j 个数字对应 4 个字符)
- 时间复杂度
- 空间复杂度 O(n) = O(i + j):
- 递归调用层数 n,空间复杂度 O(n)
phoneMap
的空间复杂度算 O(1),因为是存储了固定的 26 个字母
执行结果:
执行结果:通过
执行用时:0 ms, 在所有 C++ 提交中击败了 100.00% 的用户
内存消耗:6.3 MB, 在所有 C++ 提交中击败了 79.21% 的用户