代码随想录算法训练营第二十五天 | 216.组合总和III 17.电话号码的字母组合
组合总和III
class Solution {
public:
vector<vector<int>> combinationSum3(int k, int n) {
vector<int> path;
vector<vector<int>> result;
backtracking(k, n, path, result, 1, 0);
return result;
}
void backtracking(int k, int n, vector<int>& path, vector<vector<int>>& result, int startIndex, int count) {
// 终止条件
if(count > n) return ; // 总和大于目标值时,剪枝操作
if(path.size() == k) {
if(count == n) result.push_back(path);
return ;
}
// i < 9 - k + path.size() 做剪枝操作
for(int i = startIndex; i <= 9 - k + path.size() + 1; ++i){
// 处理节点
count += i;
// if(count > n) break; // 对于总和的剪枝操作也可以放在递归前
path.push_back(i);
// 递归
backtracking(k, n, path, result, i + 1, count);
// 回溯
path.pop_back();
count -= i;
}
}
};
17.电话号码的字母组合
思路:for循环遍历的是每个数字映射的字符集
而递归的深度由数字的个数决定,也就是digits.size();
class Solution {
private:
// 号码键映射;
string letterMap[10] = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
string combine;
vector<string> result;
public:
vector<string> letterCombinations(string digits) {
if(digits.size() == 0) return result;
backtracking(digits);
return result;
}
void backtracking(string digits, int index = 0){
// 终止条件
// 组合中的字符个数和递归深度相等时结束递归
if(combine.size() == digits.size()) {
result.push_back(combine);
return ;
}
// 取出下一层递归需要遍历的字符串
string letter = letterMap[digits[index] - '0'];
// 遍历字符串收集结果
for(int i = 0; i < letter.size(); ++i) {
combine.push_back(letter[i]);
backtracking(digits, index + 1);
combine.pop_back();
}
}
};