题目(leecode T77):
给定两个整数 n
和 k
,返回范围 [1, n]
中所有可能的 k
个数的组合。
你可以按 任何顺序 返回答案。
方法:本题最直观的解法是使用暴力for循环遍历法,根据k的大小定for循环的嵌套次数,k为多大就嵌套循环几层。但缺点也很明显,如果k很大的话,就不好写了,会显得非常的冗长。因此本题可以使用回溯法来解决,上一节的回溯法基础讲过,任何回溯问题都可以抽象成一棵树来解决。我们同样分析回溯的三部曲:
1:传入参数与返回值:需要传入给定的参数n和k,同时还有一个控制递归位置的参数startIndex
2:终止条件:因为我们会定义一个变量path用来保存一个可用的结果,因此当path的长度达到k时,我们就找到了一个符合条件的结果。
3:单层搜索的过程:for循环每次从startIndex开始遍历,然后用path保存取到的节点i。backtracking(递归函数)通过不断调用自己一直往深处遍历,总会遇到叶子节点,遇到了叶子节点就要返回。backtracking的下面部分就是回溯的操作了,撤销本次处理的结果。
题解:
class Solution {
private:
vector<vector<int>> result; // 存放符合条件结果的集合
vector<int> path; // 用来存放符合条件结果
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(); // 回溯,撤销处理的节点
}
}
public:
vector<vector<int>> combine(int n, int k) {
result.clear(); // 可以不写
path.clear(); // 可以不写
backtracking(n, k, 1);
return result;
}
};