1、描述
77给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combinations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2、关键词
组合
3、思路
回溯的模板,改一下排列的flag,用一个start作为标志来升序,树形结构的越到后面分支越少。
数组子集问题、排列、组合比较 参看
https://leetcode-cn.com/problems/combinations/solution/hui-su-si-xiang-tuan-mie-pai-lie-zu-he-zi-ji-wen-2/
剪枝参看
https://leetcode-cn.com/problems/combinations/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-ma-/
4、notes
v.pop_back(); // 撤销动作
5、复杂度
时间:
O(kCNk)
空间:
O(CNk)
6、code
class Solution {
private:
vector<vector<int>> res;
public:
vector<vector<int>> combine(int n, int k) {
vector<int>track;
backtrack(n,k,1,track); // 从1开始
return res;
}
// 用一个start来做组合问题,排列问题是用一个flag的真值来标记是否访问过
// 从start来表示 路径的升序,(免了降重)
void backtrack(int n,int k,int start,vector<int> & track)
{
if( track.size()==k) // 触底反弹
{
res.push_back(track);
return;
}
for(int i=start;i<=n;i++) // 这里是 n
{
track.push_back(i); // 把节点,记录到路径
backtrack(n,k,i+1,track); // 进入下一层
track.pop_back(); // 撤销动作
}
}
};