给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = ""
输出:[]
示例 3:
输入:digits = "2"
输出:["a","b","c"]
提示:
0 <= digits.length <= 4
digits[i] 是范围 ['2', '9'] 的一个数字。
看完题目知道知道让我们干嘛后,题目让我们解决的问题就是简单的一个组合,考虑到之多有4个数字,让我首先想到的是深度优先搜索和广度优先搜索,这里我使用的深度优先搜索,确定了主要的计算算法之后,接下来要解决的就是对应内容的存储问题,第一个考虑的是数组的,但是在后面字符拼接的时候可能没有这么方便,最后采用了键值对的方式。
关于c++的键值对分为了两种,一种是map一种是unordered_map,两者的具体差别可以参考(c++ map与unordered_map区别及使用_别说话写代码的博客-CSDN博客_unordered_map)。
题目主要结构和算法考虑完开始实现
首先键值对的创建
unordered_map<char, string>Map{
{'2', "abc"},
{'3', "def"},
{'4', "ghi"},
{'5', "jkl"},
{'6', "mno"},
{'7', "pqrs"},
{'8', "tuv"},
{'9', "wxyz"}
};
之后就是深度优先的实现,采用了重复递归调用的方式,当组合的字母个数少于输入的案按键数时进行持续的递归,最后退出
void dfs(string resultStr, int index)
{
int digitsSize = int(this->digit.size());//存储按键个数
if (digitsSize == index)
{
this->results.push_back(resultStr);
return;
}
char targetChar = this->digit[index];
string targetStr =this-> Map[targetChar];//键值对内容的读取
for (auto tmpChar : targetStr)
{
dfs(resultStr + tmpChar, index + 1);//持续递归
}
return;
}
最后进行细节优化,包括按键为零时的直接输出,以及函数传如参数的优化,能直接调用就避免新建一个传入参数
class Solution {
vector<string> results;
unordered_map<char, string>Map{
{'2', "abc"},
{'3', "def"},
{'4', "ghi"},
{'5', "jkl"},
{'6', "mno"},
{'7', "pqrs"},
{'8', "tuv"},
{'9', "wxyz"}
};
string digit;
public:
vector<string> letterCombinations(string digits) {
if(digits.length()==0)
{
return results;
}
digit=digits;用于存储变量,方便下面的调用,可以让函数少一个出入参数
dfs("", 0);
return results;
}
void dfs(string resultStr, int index)
{
int digitsSize = int(this->digit.size());//存储按键个数
if (digitsSize == index)
{
this->results.push_back(resultStr);
return;
}
char targetChar = this->digit[index];
string targetStr =this-> Map[targetChar];//键值对内容的读取
for (auto tmpChar : targetStr)
{
dfs(resultStr + tmpChar, index + 1);//持续递归
}
return;
}
};
soy 2022/1/23