题目地址:
https://leetcode.com/problems/combinations/
求 n n n个数字 1 ∼ n 1\sim n 1∼n里取 k k k个数字的全部组合。
可以用DFS。想象有 k k k个位置需要填数,我们从小到大枚举每个位置填什么数。那么每一层就是在枚举当前这个位置要填哪个数。填满 k k k个位置之后就得到了一个方案,同时可以退出递归了。代码如下:
class Solution {
public:
vector<vector<int>> combine(int n, int k) {
vector<vector<int>> res;
vector<int> v;
dfs(1, n, k, v, res);
return res;
}
void dfs(int u, int n, int k, vector<int>& v, vector<vector<int>>& res) {
if (v.size() == k) {
res.push_back(v);
return;
}
// 如果可供选择的数的个数无法填满v,则剪枝,直接退出
if (n - u + 1 < k - v.size()) return;
for (int i = u; i <= n; i++) {
v.push_back(i);
dfs(i + 1, n, k, v, res);
v.pop_back();
}
}
};
时间复杂度 O ( k ( n k ) ) = O ( n ( n − 1 k − 1 ) ) O(k{n \choose k})=O(n{{n-1}\choose {k-1}}) O(k(kn))=O(n(k−1n−1)),先产生组合数,再加入res;空间复杂度 O ( k ) O(k) O(k),递归栈深度以及v长度。