递归解决全排列问题

这个题目是我在《啊哈!算法》中看到的,题目如下:

终极问题就是: 输入一个指定点的数 N 输出1到N的全排列, 又该如何呢? 例如:输入 3 时输出 123 的全排列, 输入 4 时输出 1234 的全排歹…… 输入 9 时输出 123456789 的全排列。

看到这个题目的时候,想了半小时我都还在想,这该怎么写?

先用一个数组,把需要排列的数存起来,比如N = 3,那么,数组就是{1, 2, 3},N = 5,那么,数组就是{1, 2, 3, 4, 5},

为什么第一步我会先想到这个呢?

因为有种感觉就是,全排列特别像密码箱,{1, 2, 3}三个数字,然后这三个数字挨个滚,大家可以脑补一下,

但是这样有啥规律呢?总不能9的全排列,就写9个for循环吧?问题,能写也就算了,N的全排列,没法控制几个for循环呀,

再想一想,似乎真有些规律,

首先我们给这些数字划分个层级吧?比如{1, 2, 3},1是第一层,2是第二层,3是第三层,

当第二层的2动一下,也就是+1的时候,第三层是不是要+1加三次,才能把所有遍历给输出出来?

也就是{1, 2, 3}里的2,+1的时候变成了{1, 3, 3},那这个时候第三层是不是要这样{1, 3, 1}、{1, 3, 2}、{1, 3, 3},+3次才能把所有结果给输出出来,

接着,我们看第一层,当第一层的1,+1的时候,是不是第二层也要像上面这样+3次,才能把第二层给完全输出出来?

OK,我们现在就找到规律了,当每一层的数字变动的时候(通常是+1),该层的下一层就要从1到N遍历一遍,每一层我们都可以用数组给存起来,当到达第N层的时候,我们就可以判断这个数据是不是符合题目的数据了。

下面是代码:

package com.ziyu.aha;

/**
 * @ClassName test2
 * @Date
 * @Author
 * @Description TODO
 **/
public class test2 {

    static int[] iarray;

    static int sum = 0;
    // {1, 2, 3, 4, 5}
    public static void tt(int n){

        iarray = new int[n+1];
        digui(1, n);

    }

    public static void main(String[] args){
        tt(4);
        System.out.println(sum);
    }

    public static void digui(int level, int max){

        for (int i = 1; i <= max; i++){

            iarray[level] = i;
            if (level >= max){
                if (right(iarray)) {
                    sum++;
                    show(iarray);
                }
            }else{
                digui(level+1, max);
            }

        }

    }

    //判断数组是否符合  桶排序
    public static boolean right(int[] a){

        int[] ton = new int[a.length];

        for (int i = 1; i < a.length; i++){
            ton[a[i]]++;
        }

        for (int i = 1; i < ton.length; i++){
            if (ton[i] > 1){
                return false;
            }
        }

        return true;

    }

    public static void show(int[] a){
        for (int i = 1; i < a.length; i++)
            if (i == a.length - 1)
                System.out.print(a[i]);
            else
                System.out.print(a[i] + ",");
        System.out.println();
    }

}

在判断的时候,我使用的是桶排序判断数组,感兴趣的可以自行搜索。

如果有什么疑问,可以在下面留言,欢迎交流提意见

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值