题目
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例
示例 1:
输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]示例 2:
输入:digits = "" 输出:[]示例 3:
输入:digits = "2" 输出:["a","b","c"]
分析
回溯
时间复杂度:O(),
输入数字中对应 3 个字母的数字个数,
是输入数字中对应 4 个字母的数字个数
空间复杂度:O()
class Solution {
private:
// 定义数字到字母的映射
std::unordered_map<char, std::string> phoneMap = {
{'2', "abc"},
{'3', "def"},
{'4', "ghi"},
{'5', "jkl"},
{'6', "mno"},
{'7', "pqrs"},
{'8', "tuv"},
{'9', "wxyz"}
};
std::vector<std::string> result;
std::string current;
// 回溯函数
void backtrack(const std::string& digits, int index) {
if (index == digits.length()) {
// 当遍历完所有数字,将当前组合加入结果集
result.push_back(current);
return;
}
char digit = digits[index];
std::string letters = phoneMap[digit];
for (char letter : letters) {
// 选择当前字母
current.push_back(letter);
// 递归调用,处理下一个数字
backtrack(digits, index + 1);
// 回溯,撤销选择
current.pop_back();
}
}
public:
std::vector<std::string> letterCombinations(std::string digits) {
if (digits.empty()) {
return {};
}
backtrack(digits, 0);
return result;
}
};
知识充电
回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。
模板
#include <vector>
// 回溯函数模板
void backtrack(std::vector<int>& path, std::vector<int>& choices, std::vector<std::vector<int>>& result) {
// 终止条件:判断是否满足解的条件
if (isSolution(path)) {
result.push_back(path);
return;
}
// 遍历所有可能的选择
for (int choice : choices) {
// 做出选择
if (isValid(choice, path)) {
path.push_back(choice);
// 递归调用,继续搜索
backtrack(path, choices, result);
// 撤销选择
path.pop_back();
}
}
}
// 判断是否为一个有效的解
bool isSolution(const std::vector<int>& path) {
// 这里根据具体问题实现判断逻辑
// 例如,当 path 的长度达到某个值时认为是一个解
return path.size() == 某个特定长度;
}
// 判断当前选择是否有效
bool isValid(int choice, const std::vector<int>& path) {
// 这里根据具体问题实现判断逻辑
// 例如,检查选择是否已经在 path 中出现过
for (int p : path) {
if (p == choice) {
return false;
}
}
return true;
}