77. 组合:代码随想录
这道题目的意思就是让你返回从一到n中所有可能的k个数的组合,这道题我们采用的是回溯的方法,首先,回溯最重要的就是递归的部分,递归函数的参数以及返回值,还有递归的终止条件,以及单层递归的逻辑,首先定义两个动态数组,然后就是传入的参数为n,k,还有控制下标的startindex,因为不能出现重复的情况,所以要控制下标,然后就是终止条件,当我数组的长度等于k的值时,这个时候代表我要将该数组加入到我的结果数组中,否则的话我就for循环,这里的for循环相当于那个递归树的宽度,而递归函数的嵌套调用就相当于我递归树的深度,然后在for循环里面依然是int i=startindex,这样递归的传入stratindex才能保证我一直是在找后面的数,这样就不会重复,然后就是pushback元素,接着递归调用,然后递归调用结束后将元素弹出,最后返回result数组即可。
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
vector<vector<int>> combine(int n, int k) {
backtracking(n, k, 1);
return result;
}
void backtracking(int n, int k, int startindex) {
if (path.size() == k) {
result.push_back(path);
return;
}
for (int i = startindex; i <= n; i++) {
path.push_back(i);
backtracking(n, k, i + 1);
path.pop_back();
}
}
};
注意这里的剪枝优化操作,因为如果我的k等于2,而此时已经遍历到我的数组的最后一位了,那其实就没有必要再去遍历了,因为后面的元素个数都没有k个,所以我们这里可以得出一个式子——k-path.size()代表我还需要加入多少元素,而n-(i-1)代表我还剩下多少个元素没有遍历,只有前面的式子小于等于我我后面的式子时,才有结果,否则,就不需要再继续遍历了。
216.组合总和III:代码随想录
这道题目其实和上一道题目一样,只不过是加了一些约束条件,直接来看代码
class Solution {
public:
vector<vector<int>> result;
vector<int> ans;
vector<vector<int>> combinationSum3(int k, int n) {
dfs(n, k, 1, 0);
return result;
}
void dfs(int n, int k, int index, int sum) {
if (k==0 && sum == n) {
result.push_back(ans);
return ;
}
for (int i = index; i <= 9; i++) {
ans.push_back(i);
dfs(n, k-1, i + 1, sum + i);
ans.pop_back();
}
}
};
当我数组里的元素个数等于我的k并且我的元素数值的总和等于我的n时,就代表此时我要收集我的结果集,,否则的话,我就要进入for循环,这里和上面一样,只不过是加了一个参数sum
17.电话号码的字母组合:代码随想录
这道题目其实也是一样,直接看代码
class Solution {
public:
vector<string> result;
string ans="";
string d[10] = { "","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz" };
vector<string> letterCombinations(string digits) {
if(digits.size()==0) return result;
backtracking(0, digits.size(), digits);
return result;
}
void backtracking(int index,int size,string s) {
if (ans.size() == size) {
result.push_back(ans);
return;
}
for (int i = index; i < size; i++) {
int a = s[i] - '0';
a--;
string t = d[a];
for (int j = 0; j < t.size(); j++) {
string ans1 = ans;
ans += d[a][j];
backtracking(i + 1, size, s);
ans = ans1;
}
}
}
};
同样的当元素个数达到传入字符串的大小时,返回结果,这里最主要的不同是有两个for循环,但其实都是一样的,只不过是树的宽度变宽了而已。