代码随想录算法训练营第25天|216.组合总和III,17.电话号码的字母组合
216.组合总和III
题目链接:216.组合总和III,难度:中等
【实现代码】
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(int k, int n, int startIndex) {
if (n == 0 && path.size() == k) {
result.push_back(path);
return ;
}
if (path.size() > k) {
return ;
}
for (int i = startIndex; i < 10; i++) {
if (i > n) {
return ;
}
path.push_back(i);
backtracking(k, n - i, i + 1);
path.pop_back();
}
return ;
}
public:
vector<vector<int>> combinationSum3(int k, int n) {
backtracking(k, n, 1);
return result;
}
};
【解题思路】
组合问题使用回溯算法。
回溯三部曲:
- 确定函数的结束条件:这里是k个数的和等于n时结束,或者当数量超过k时还没有等于n也结束
- 确定函数参数:这里需要总数k,总和n,以及开始索引
- 确定单层逻辑:存进path,并进行下一层递归,递归结束移除上一个数
17.电话号码的字母组合
题目链接:17.电话号码的字母组合,难度:中等
【实现代码】
class Solution {
private:
vector<string> result;
string path = "";
void backtracking(const vector<vector<char>>& nums, string digits, int startIndex) {
if (path.size() == digits.size()) {
result.push_back(path);
return ;
}
for (int i = startIndex; i < digits.size(); i++) {
for (int j = 0; j < nums[digits[i]-'0'].size(); j++) {
path += nums[digits[i]-'0'][j];
backtracking(nums, digits, i + 1);
path.erase(path.size() - 1, 1);
}
}
return ;
}
public:
vector<string> letterCombinations(string digits) {
if (digits.size() == 0) {
return result;
}
vector<vector<char>> nums;
vector<char> tmp;
nums.push_back(tmp);
nums.push_back(tmp);
for (char i = 'a'; i <= 'z'; i++) {
tmp.push_back(i);
if (tmp.size() >= 3 && tmp.back() != 'r' && tmp.back() != 'y') {
nums.push_back(tmp);
tmp.clear();
}
}
backtracking(nums, digits, 0);
return result;
}
};
【解题思路】
组合问题使用回溯算法。
回溯三步曲:
- 确定结束条件:当path的长度为输入数字的长度时结束
- 确定函数参数:数字和字母的对应关系,输入的数字,以及下一个索引
- 单层逻辑:首先取出第一个数字代表的字母集合中一个字母,再取下一个数字代表的字母集合中一个字母,结束时取第一个数字代表的字母集合中另一个字母…