蓝桥杯算法辅导之:全排列问题

题目信息

把 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);
    }
}

猜你喜欢

转载自blog.csdn.net/guankunkunwd/article/details/122588298