全排列算法

全排列算法详细解析

全排列在笔试面试和ACM竞赛中很热门,因为它难度适中,既可以考察递归实现,又能进一步考察非递归的实现,便于区分出考生的水平。(自己的心得:回溯是思想,深搜是本质,递归是实现

一、全排列的递归实现(以下所有代码以java为主)

以abcd为例,共有24种排列方式,abcd,abdc,acbd,acdb…….,因此可以知道——全排列就是从第一个数字起每个数分别与它后面的数字交换。递归的代码如下:

public class Main{
    public static int count=0;
    public static void swap(char[] a,int i,int j){
        char tmp = a[i];
        a[i]=a[j];
        a[j]=tmp;
}

    public static void perm(char[] a,int st,int len){
        if(st==len-1){
            for(int i=0;i<len;i++){
                System.out.print(a[i]);
            }
            System.out.println("");
            count++;
        }else{
            for(int i=st;i<len;i++){
                swap(a,st,i);
                perm(a,st+1,len);
                swap(a,st,i);
            }
        }
    }
    public static void main(String[] args) {
        char[] a="abcd".toCharArray();
        perm(a,0,4);
        System.out.println("总共有:"+count+"种");
    }
}
运行结果如下:

全排列的结果

二、以蓝桥杯里面的一道例题来使用全排列解决

题目:
凑算式: A+B/C+DEF/GHI = 10
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。比如: 6+8/3+952/714就是一种解法, 5+3/1+972/486是另一种解法。这个算式一共有多少种解法?

代码如下:

public class Main {
    static int count=0;
    public static void swap(char[] a,int i,int j){
        char temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }
    public static boolean check(char[] a){
        double[] num = new double[9];
        for(int i=0;i<9;i++){
            num[i]=a[i]-'0';
        }
        if(num[0]+num[1]*1.0/num[2]+(num[3]*100+num[4]*10+num[5])*1.0/(num[6]*100+num[7]*10+num[8])==10){
            return true;
        }
        return false;
    }

    public static void perm(char[] a,int st,int length){
        if(st==length-1){
            if(check(a)){
                count++;
            }
        }else{
            for(int i=st;i<length;i++){
                swap(a,st,i);
                perm(a,st+1,length);
                swap(a,st,i);
            }
        }
    }
    public static void main(String[] args) {    
        char[] a="123456789".toCharArray();
        perm(a,0,9);
        System.out.println("共有"+count+"种解法");
    }
}
运行结果如下:

总结:

全排列就是从第一个数字起每个数分别与它后面的数字交换

-------------本文结束感谢您的阅读-------------
创作不易,您的支持就是我坚持的动力,谢谢大家!
0%