题目
解答
思路
map存储key-value组合、dfs回溯解决。
需要的头文件
string、vector、algorithm、unordered_map
代码
/*
* @lc app=leetcode.cn id=17 lang=cpp
*
* [17] 电话号码的字母组合
*/
// @lc code=start
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
class Solution
{
public:
vector<string> letterCombinations(string digits)
{
//这里也可以将这三个变量选择放在public处,dfs就不需要引用那么多参数了,但是不安全
unordered_map<char, string> phonemap = {{'2', "abc"}, {'3', "def"}, {'4', "ghi"}, {'5', "jkl"}, {'6', "mno"}, {'7', "pqrs"}, {'8', "tuv"}, {'9', "wxyz"}};
//combinations是总的返回答案,one_comb_str是每一次搭配得出的字母组合,pos是对应digits长度的字母组合长度指针
vector<string> combinations;
string one_comb_str;
//特殊情况
if (digits.empty())
{
return combinations;
}
NumToLetter_dfs(0, combinations, one_comb_str, phonemap, digits);
return combinations;
}
void NumToLetter_dfs(int pos, vector<string> &combinations, string &one_comb_str, const unordered_map<char, string> &phoneMap, const string &digits)
{
//pos等于digits,也就是一次组合完毕后,可以回到上一级
//比如"23",得出"ad"后返回上一级
if (pos == digits.size())
{
// 将这次的组合词放入combinations中
combinations.push_back(one_comb_str);
return;
}
//进入正常流程,以下以"23"为例
else
{
//先找到'2',然后从map中找到'2'对应的 "abc"
string letters = phoneMap.at(digits[pos]);
//C++11 里面的for的新写法,表示依次取出字符串数组letters中的元素,赋给变量letter
//对比python的range,是不是感觉很像!
//分次取出a,b,c
for (char letter : letters)
{
//第一次循环会放入a,之后两次循环就是b和c
one_comb_str.push_back(letter);
//回溯,这一步我们可以一次性得到 "ad" "ae" "af",之后请如法炮制
NumToLetter_dfs(pos + 1, combinations, one_comb_str, phoneMap, digits);
//如果第一次循环到这了,说明 a 的部分已经检查完了,下一次就到b了
one_comb_str.pop_back();
}
//最后说一下清晰的顺序,第一次正常流程先push'a',然后回溯,检测到长度不够,继续push'd',继续回溯
//此时检测到长度满足,放入返回数组中,return,跳到最后一句,把'd'pop出来
//请注意这时候的for循环在第二层(是3对应的 "def"那层,而不是最外层的2对应的 "abc"层)
//所以下一步循环会放入'e',而不是'b',好好想清楚!
}
}
};
// @lc code=end
时间复杂度和空间复杂度(此处复制了官方解释,准确到位。)
-
时间复杂度: O(3m * 4n ) ,其中 m 是输入中对应 3 个字母的数字个数(包括数字 2、3、4、5、6、8),n 是输入中对应 4 个字母的数字个数(包括数字 7、9),m+n 是输入数字的总个数。当输入包含 m 个对应 3 个字母的数字和 n 个对应 4 个字母的数字时,不同的字母组合一共有3n * 4m种,需要遍历每一种字母组合。
-
空间复杂度:O(m+n) ,其中 m 是输入中对应 3 个字母的数字个数,n 是输入中对应 4 个字母的数字个数,m+n是输入数字的总个数。除了返回值以外,空间复杂度主要取决于哈希表以及回溯过程中的递归调用层数,哈希表的大小与输入无关,可以看成常数,递归调用层数最大为 m+n。
反思与总结
dfs经典用法,需要牢记。另外要多接触 for (char letter : letters)
这种新写法,C++11的新特性,类比python的range