算法竞赛进阶指南-6.递归实现组合型枚举
题目链接
从 这 个整数中随机选出 个,输出所有可能的选择方案 => 即
同一行内的数升序排列,相邻两个数用一个空格隔开
对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面
Method : 递归
本题相较上一个题目,多一个(select == m)的条件。
其次,可以使用剪枝去优化时空复杂度,n + 1 - depth < m - select
是表示剩下的数量 < 要选的数量。
#include <vector>
#include <iostream>
using namespace std;
int n, m;
vector<int> choosen;
void dfs(int depth, int select) {
// prune
if (select > m || n + 1 - depth < m - select) {
return;
}
// boundary
if (select == m) {
for (int i = 0; i < choosen.size(); i ++) {
printf("%d ", choosen[i]);
}
cout << endl;
return;
}
if (depth == n + 1) return;
choosen.emplace_back(depth);
dfs(depth + 1, select + 1);
// recover
choosen.pop_back();
dfs(depth + 1, select);
}
int main() {
cin >> n >> m;
dfs(1, 0);
return 0;
}
复杂度分析
时间复杂度, 其中为递归函数栈的深度。 但由于剪枝,实际时间复杂度会小于该理论时间复杂度。
空间复杂度,数组的空间为,另外递归函数栈会花费额外常数级空间。
本博客所有文章均采用 CC BY-NC-SA 4.0 协议 ,禁止商用,转载请注明出处!