题目描述
给定一个整数n,将数字1~n排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。
算法:爆搜(排列型枚举)
时间复杂度:$N!$
排列型枚举
排列型枚举一般要判断该数是否被被枚举过,且相同数字需要定义插入的方向防止排列出现冗余的情况
本道题目特殊在没有出现重复的数字,所以不需要相同的数字需要定义插入的方向
方法1:bool数组判重
#include<iostream>
using namespace std;
const int N=10;
int path[N];
bool st[N];
int n;
void dfs(int u)
{
if(u==n){
for(int i=0;i<n;i++)cout<<path[i]<<" ";
puts("");
return;
}
for(int i=1;i<=n;i++){
if(!st[i]){
st[i]=true;
path[u]=i;
dfs(u+1);
st[i]=false;
}
}
}
int main()
{
scanf("%d",&n);
dfs(0);
return 0;
}
方法2:二进制数状态标记法
传递二进制标记作为枚举的状态信息
#include<iostream>
#include<cstring>
using namespace std;
const int N=10;
int path[N];
int n;
void dfs(int u,int state)
{
if(u==n){
for(int i=0;i<n;i++)cout<<path[i]<<" ";
puts("");
}
for(int i=1;i<=n;i++){
if(!(state>>i&1)){
state+=1<<i;
path[u]=i;
dfs(u+1,state);
state-=1<<i;
}
}
}
int main()
{
cin>>n;
dfs(0,0);
return 0;
}