94. 递归实现排列型枚举
相当于一个不重复序列的全排列问题,图示如下:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n;
int x[10]; //标记当前是否被选择过
int num[10];//记录当前所选数据
void dfs(int current)
{
if(current>n)//到达叶子结点输出结果
{
for(int i=1; i<=n; i++)
cout<<num[i]<<' ';
cout<<endl;
return ;
}
for(int i=1;i<=n;i++)//遍历每个数
{
if(x[i]==0)//未被选择过
{
num[current]=i;
x[i]=1;
dfs(current+1);
//回溯时恢复
x[i]=0;
}
}
}
int main()
{
cin>>n;
dfs(1);
return 0;
}
/*
输入:
3
*/
输出
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
1537. 递归实现排列类型枚举 II
此题和上一个题类似,只是num数组赋值的时候应该为a[i],此外还需要考虑输出结果重复的情况,为了方便排除重复情况先将输入的数组a进行排序,使得重复的数字相接,同时要设置 “当前数=前一个数&&上一个数未被选中” 则跳过当前数的选择。这样若前后两个数相同,则必须保证其放入x数组的顺序,使得重复的排列被去掉。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n;
int x[10]; //标记当前是否被选择过
int num[10],a[10];//记录当前所选数据
void dfs(int current)
{
if(current>n)//到达叶子结点输出结果
{
for(int i=1; i<=n; i++)
cout<<num[i]<<' ';
cout<<endl;
return ;
}
for(int i=1; i<=n; i++) //遍历每个数
{
//如果前一个数和当前数相同,且上一个数未被被选中则不进行当前数的选择
if(a[i-1]==a[i] && x[i-1]==0)
continue;
if(x[i]==0) //未被选择过
{
num[current]=a[i];
x[i]=1;
dfs(current+1);
//回溯时恢复
x[i]=0;
}
}
}
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
cin>>a[i];
sort(a,a+n+1);
dfs(1);
return 0;
}
/*
3
1 2 2
*/
输出
1 1 2
1 2 1
2 1 1