使用递归求全排列

来源:互联网 发布:大数据 课程 编辑:程序博客网 时间:2024/05/22 12:09

全排列:如123三个数字的全排列:123,132,213,231,312,321;可以使用穷举的方式使用三个for循环来解决。但是如果数字很多或者数字的个数不确定那肯定不能用这种方法。

以一个案例来说明。
假设手上有三封信123,三个信箱123,将三封信投递到三个信箱中正是一个全排列问题。

信箱1 信箱2 信箱3 (信箱4)

信1 信2 信3

假设是以上投法,当信全部投完,需要从信箱3中把信3拿出,把信2从信箱2中拿出,此时,从换种投法将信3投到信箱2,信2投到信箱3(a.想想这个怎么实现的,后面解答),这样得到了另一种排列。

因为每封信只能投一次,(b.用一个标记数组book[3]来标记每封信是否在手上)。

以上投法可以看出,对每个信箱的投信法都是一样的,只是信箱编号变了和手里的信少了。

因此,程序可以写成这样。

package test;public class Permutation {    int[] box = new int[3] ,book = new int[3];    public static void main(String[] args){        new Permutation().push(0);    }    void push(int boxNum){        if(boxNum == 3){            for(int a : box){                System.out.print(a);//              System.out.println();            }            System.out.println();//          return ;不写也没毛病        }        for(int i = 0; i<3;i++){            if(book[i] == 0){    //信在手中                box[boxNum] = i;                book[i] =1;                System.out.println("信"+i+"投递到"+"信箱"+boxNum);                push(boxNum+1);                book[i]=0;                System.out.println("回收信"+i);            }        }    }}

结果如下

信0投递到信箱0信1投递到信箱1信2投递到信箱2012回收信2回收信1信2投递到信箱1信1投递到信箱2021回收信1回收信2回收信0信1投递到信箱0信0投递到信箱1信2投递到信箱2102回收信2回收信0信2投递到信箱1信0投递到信箱2120回收信0回收信2回收信1信2投递到信箱0信0投递到信箱1信1投递到信箱2201回收信1回收信0信1投递到信箱1信0投递到信箱2210回收信0回收信1回收信2

a处的标记看了程序之后就能明白,信封i和信箱boxNum在回收信时会错位,达到了改变投递方法的效果。
先回收再投递。

递归就是考虑当前的要做的是,下一步和当前的方法一样,要有结束条件。

0 0
原创粉丝点击