216.组合总和III
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void func(int k, int sum, int targetsum, int st){
if(path.size() == k){
if(sum == targetsum) res.push_back(path);
return;
}
for(int i = st; i <= 9-(k-path.size())+1; ++i){
if(sum > targetsum) return;
sum += i;
path.push_back(i);
func(k, sum, targetsum, i+1);
sum -= i;
path.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
func(k, 0, n, 1);
return res;
}
};
解题心得:
照旧先看如何添加子答案。首先是当path里添加k个数字后就开始判断,如果sum和目标n相等,说明是一个合理的答案,添加进res总答案中,最后无论是找到了答案,或者找到了k个但是sum 不相同,这都需要return。
循环依旧是从头开始遍历,递归依旧是通过st来进行调控,进行一层层的递归相加。剪枝的话可以再每次进循环的时候,判断一下上层递归的sum是否已经大于了目标和,如果已经大于了,则就直接return,不需要遍历。
同时void函数不写return也ok(不要纠结一些奇怪的东西。。)
17.电话号码的字母组合
class Solution {
public:
const string numbers[10] ={
"", //0
"",//1
"abc",//2
"def",//3
"ghi",//4
"jkl",//5
"mno",//6
"pqrs",//7
"tuv",//8
"wxyz",//9
};
string path;
vector<string> res;
void func(string digits, int st){
if(path.size() == digits.size()){
res.push_back(path);
return;
}
int digit = digits[st] - '0';
for(int i = 0; i < numbers[digit].size(); ++i){
path += numbers[digit][i];
func(digits, st + 1);
path.erase(path.size() - 1);
}
}
vector<string> letterCombinations(string digits) {
if(digits.size() == 0) return res;
func(digits, 0);
return res;
}
};
解题思路:
首先是通过一个二维字符串进行映射,电话上的数字对应每个字符串的下标。
收获结果时刻:当用作收集字符串的子答案等于按下的数字数量,那就是形成了一个子答案,可以放入大的vector中
循环遍历时刻,最外层的 for 用作遍历最前面字符串的每个字符,递归的是下一个数字对应的字符串,然后一层层的往下递归。比较需要注意的是,这里面的 st 是在哪里进行迭代变更。
还可以关注一下的是, string 同样可以使用 push_back 和 pop_back 函数,不过我没使用。