2025/8/24
题目(Medium):

我的思路:
很显然这题也可以用递归的方式来进行处理。我们对按顺序处理每一个数字,把它对应的字符加入结果种,再去递归处理它的下一位数字能得到的字符结果。当达到了长度之后就会把它加入到结果集种,之后再回溯到上一个位置,移除之前加入的字符,并尝试这个数字对应的下一个字符。
大致的步骤如下:
①声明一个哈希表用来映射数字字符和它对应的字符串
②回溯函数的递归终止条件:当前结果长度和目标长度相等,就把当前结果加入结果集中
③回溯函数的处理:获取当前位置的对应的数字字符,把该数字字符对应的字母加入结果
④回溯函数的递归:递归处理结果的下一位
⑤回溯:回溯到当前位置之后,再选择该数字字符对应的之前没有加入到结果中的字母
⑥递归都结束之后返回结果集
具体代码如下:
class Solution {
private:
vector<string> res;
unordered_map<char, string> letterMap = {
{'2', "abc"},
{'3', "def"},
{'4', "ghi"},
{'5', "jkl"},
{'6', "mno"},
{'7', "pqrs"},
{'8', "tuv"},
{'9', "wxyz"}
};
void backTrack(string& digits, string& output, int curIndex){
if(output.size() == digits.size()){
res.emplace_back(output);
return;
}
//对每个数字字符进行处理
char c1 = digits[curIndex];
//对每个数字字符对应的字母进行处理
for(const auto& c2 : letterMap[c1]){
output += c2;
backTrack(digits, output, curIndex + 1);
output.pop_back();
}
}
public:
vector<string> letterCombinations(string digits) {
if(digits == "")
return {};
string output;
backTrack(digits, output, 0);
return res;
}
};
时间复杂度:O(3^m×4^n)【m是对应3个字母的数字个数,n是对应4个字母的数字个数,需要遍历所有的组合可能性】
空间复杂度:O(m+n)【递归调用层的最大深度为m+n】
总结:
①对于这种需要遍历每一种组合的题目,用回溯的思想去做是最简单直观的
②对于这种每个元素有顺序限制的题目(比如这里“23”和“32”对应的答案不同且唯一),我们在递归的时候也按顺序递归来进行处理。对于不需要按顺序的题目(比如全排列[321]和[123]都是答案的一部分)我们就需要每次递归的时候都注意对每个数再进行从头遍历处理(当然这个也可以把他优化成按某种规定的顺序的,比如之前全排列中规定first指针左侧是已经排列好的,右侧是未排列的,这样也相当于让他有一定的顺序限制了)

482

被折叠的 条评论
为什么被折叠?



