题目信息
把 1∼n 这 n 个整数排成一行后随机打乱顺序,输出所有可能的次序
。
输入格式
一个整数 n
输出格式
按照从小到大的顺序输出所有方案,每行 1 个。
首先,同一行相邻两个数用一个空格隔开。
其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面
输入样例:
3
输出样例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
思路
全排列问题和递归实现指数型枚举很相似,也是递归问题。
想了解递归实现指数型枚举参考文章 文章链接在这里。
只不过全排列问题是不管顺序的,而且每个数字都要打印出来。我们可以画一棵递归搜索树来表示搜索的过程。为了不重答案,我们采取依次枚举每个数放到哪个位置的递归策略。图如下。
代码
import java.util.Scanner;
/**
* Created with IntelliJ IDEA.
* @Description: 全排列
*/
public class Main {
static int N=15;
//定义一个Boolean类型的st数组表示状态,代表当前这个数有没有被用过了。
static boolean st[]=new boolean[N];
static int n=0;
//记录已经走过的方案
static int path[]=new int[N];
static void dfs(int u){
//如果u>n了,说明已经递归完了一种方案了,输出这个方案
if(u>n){
for (int i =1 ; i <=n ; i++) {
System.out.print (path[i]+" ");
}
//输出一种后打印换行,return结束
System.out.println ();
return;
}
//对于1-n枚举每一个数
for (int i = 1 ; i <=n ; i++) {
//如果i还没有走过,就进入if的判断
if(st[i]==false){
//先将i的状态标记成true。表示走过了
st[i]=true;
//记录这时候的path
path[u]=i;
//递归到下一层
dfs (u+1);
//回溯,将上次修改的改回来
st[i]=false;
}
}
}
public static void main (String[] args) {
Scanner s=new Scanner (System.in);
n=s.nextInt ();
dfs (1);
}
}