生成子集笔记
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
代码如下
dfs
class Solution {
public:
vector<vector<int>> combine(int n, int k) {
vector<vector<int>> ans;
vector<int> cur;
function<void(int)> dfs = [&](int s) {
if (cur.size() == k) {
ans.push_back(cur);
return;
}
for (int i = s; i < n; ++i) {
cur.push_back(i + 1);
dfs(i + 1);
cur.pop_back();
}
};
dfs(0);
return ans;
}
};
下面以[1,2,3,4] k=2画一下执行流
s=0,cur=[]
i=0
cur=[1],s=1
i=1
cur=[1,2],s=2 终止
i=2
cur=[1,3],s=3 终止
i=3
cur=[1,4],s=4 终止
i=1
cur=[2],s=2
i=2
cur=[2,3],s=3 终止
i=3
cur=[2,4],s=4 终止
i=2
cur=[3],s=3
i=3
cur[3,4],s=4 终止
i=4 不会出现
i=3
cur=[4],s=4
i=4 不会出现
可见其执行规律相当于是每一次都以不同的位置开始,但是i<n
规定了可选集合。所以选择方法是很核心的一个想法
s表示必须选择的位置,这样从第一个位置必须选择,到第二个位置必须选择,就可以不重不漏的生成集合了。而事实上,我们也是这样思维的。