根据题目所给的数据范围提示选择相应的时间复杂度的算法。
题目:
把 1∼n1∼这 n 个整数排成一行后随机打乱顺序,输出所有可能的次序。
输入格式
一个整数 n。
输出格式
按照从小到大的顺序输出所有方案,每行 11 个。
首先,同一行相邻两个数用一个空格隔开。
其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面。
数据范围
1≤n≤9
解题思路:
主思路:依次枚举每个位置可以放哪个数
该思路对应的递归搜索树(每个分支对应该位置可以放的数)为下图:
相应的算法实现代码为:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
const int N=10;
int n;
int state[N];//用于存放方案的每一个数
bool used[N];//记录1~n数是否被使用,0代表未使用,1代表已被使用
void dfs(int u)
{
state[0]=1;
if(u>n)
{
for(int i=1;i<=n;i++)
printf("%d ",state[i]);
printf("\n");
return;
}//若u>n,递归出口,输出方案
for(int i=1;i<=n;i++)//每个位置可以放那些数,每次都是从1开始遍历没有被使用过的数,保证字典序小的排在前面。
{
if(!used[i])
{
state[u]=i;
used[i]=true;
dfs(u+1);
state[u]=0;//恢复现场,有无都行,有的话更好地展现算法的具体实现细节,没有的话state[u]也会被上层的另一个分支的state[u]=i操作覆盖
used[i]=false;//恢复状态
}
}
}
int main()
{
scanf("%d",&n);
dfs(1);
return 0;
}
注:每个位置通过线性枚举未用过的数,当u>n时,表明已经选择了n个数,为递归边界,输出该方案。