Permutation
不含重复元素
问题描述
给一个大小为n为数组a,a内的元素互不相同,要求求出 A(n,k) 。
思路
直接dfs即可。
枚举当前位需要放的数字,然后看前面是否出现。
代码
// a is original array
void dfs(vector<int> t, int step) {
if (step == k) {
ans.push_back(t);
return;
}
for (auto x : a) {
bool ok = true;
for (int j = 0; j < step; j++)
if (t[j] == x) ok = false;
if (ok) {
t.push_back(x);
dfs(t, step + 1);
t.pop_back();
}
}
}
包含重复元素
问题描述
给一个大小为n为数组a,a内的元素有重复的,要求求出 A(n,k) 。比如:[1, 1, 2],求出 A(3,2) 为:[1, 1], [1, 2], [2, 1]。
思路
基本思路和不含重复元素一样,但是还需要去重。
去重的关键是:对于a中两个相同的元素,比如 ai 和 ai+1 ,要使用 ai+1 的时候:当且仅当 ai 已经被使用。
代码
int vis[maxn];
void dfs3(vector<int>& t, int step) {
if (step == k) {
ans.push_back(t);
return;
}
for (int i = 0; i < a.size(); i++) {
if (vis[i]) continue;
if (i && a[i] == a[i - 1] && !vis[i - 1]) continue;
vis[i] = 1; t.push_back(a[i]);
dfs3(t, step + 1);
vis[i] = 0; t.pop_back();
}
}
Combination
不含重复元素
问题描述
给一个大小为n为数组a,a内的元素互不相同,要求求出 C(n,k) 。
思路
直接dfs。对于a中的每一个元素,我们选择放和不放即可。
代码
void dfs(vector<int> t, int cur, int step) {
if (cur >= n) {
if (step == k) ans.push_back(t);
return;
}
t.push_back(a[cur]);
dfs(t, cur + 1, step + 1);
t.pop_back();
dfs(t, cur + 1, step);
}
包含重复元素
问题描述
给一个大小为n为数组a,a内的元素有重复的,要求求出 C(n,k) ,比如[1, 1, 2]的 C(3,2) 为:[1, 1], [1, 2]。
思路
基本思路和不含重复元素一样,但是需要去重。
去重:对于a中两个相同的元素,比如 ai 和 ai+1 ,要使用 ai+1 的时候:当且仅当 ai 已经被使用。
代码
void dfs(vector<int> t, int cur, int step) {
if (cur >= n) {
if (step == k) ans.push_back(t);
return;
}
if (cur && a[cur] == a[cur - 1] && !vis[cur - 1]) return;
vis[cur] = 1;
t.push_back(a[cur]);
dfs(t, cur + 1, step + 1);
t.pop_back();
vis[cur] = 0;
dfs(t, cur + 1, step);
}