77.组合
题目描述:
给定两个整数 n
和 k
,返回范围 [1, n]
中所有可能的 k
个数的组合。
你可以按 任何顺序 返回答案。
示例一:
输入:n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
示例二:
输入:n = 1, k = 1
输出:[[1]]
提示:
1 <= n <= 20
1 <= k <= n
解题思路:
- 关键词提取:两个整数、数值范围[1,n]、k个数组合、任意顺序
- 回溯解法:
- 层数k,在达到k层时,将结果保存
- 选值范围[1,n],由for循环做遍历寻值
- 每个值只能用一次,需要用index去记录起始位置,每层从起始位置开始寻值
代码如下:
class Solution {
private:
// 定义一个储存返回结果的二维数组
vector<vector<int>> result;
// 定义一个储存单次结果的一维数组
vector<int> path;
// 递归函数,需要传递的参数有数值范围n,层数k,起始位置startIndex
void backtracking(int n, int k, int startIndex) {
// 终止条件,单次结果的数组长度达到层数k
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();
// 题目取值范围从1-n
backtracking(n, k, 1);
return result;
}
};
总结:
-
二刷,采用回溯算法的模板去做,逻辑很清晰。
- 解题:组合类,元素不能重复,任意顺序。满足回溯法的前提条件。
- 模板:
1、确认递归函数
2、确认递归终止条件
3、确认结果集的存数逻辑
4、确认单层遍历的起始位置
5、确认单次结果取数逻辑
6、确认递归函数的起始状态
7、确认单次递归的回溯逻辑
-
代码随想录讲解的很详细,有兴趣的小伙伴可以去研究一下。
- 讲解视频:https://www.bilibili.com/video/BV1ti4y1L7cv/
- 值得深究的地方:剪枝和去重,我理解还不够,建议大家伙儿还是直接去看carl哥的讲解视频比较合适。