字典序算法

字典序算法

字典序

就是按照字典中出现的先后顺序进行排序

  1. 单个字符
    在计算机中,25个字母以及数字字符,字典排序如下:
    字母 : ABCDE~XYZ
    数字:12345678~
  2. 多个字符
    两个字符串比较大小,是按照从左到右的顺序进行比较,如果第1位相等,就比较第2位,直至有一位可以比较出大小来,则不再继续比较。
  3. 全排列的字典
    给定多个字符或者字符,可以按照任意顺序进行排列,所有排列称为全排列。
    每一种排列对应一个字符串,如果这些字符串按照字符串大小的顺序进行排序,那么就这种排序是基于字典序的全排列。

字典序算法

解决问题 : 给定其中一种排列,求基于字典序的下一种排列(求全排列的下一个数)。

eg: 给出 1,2,3,4,5,6 这6个数。 求 组成的任意一个整数A 的全排列下一个数。(通俗点:求一个包含这6个数的 整数,要求 大于且仅大于原数 A)
例如 :
123456-》 123465
123546-》123564
124356-》124365

654321=》由于是排列中的最大数,所以没有下一个排列。

综上,为了接近原数,我们 要尽量 保持高位不变,低位在最小范围内变换顺序
至于变换顺序的范围,则取决于当前整数的逆序区。

获取 全排列下一个数的步骤:

在这里插入图片描述

   /**
     * 获取全排列的下一个数
     * @return
     */
    public static int[] findNextPermutation(int[] array){

        int[] datas = Arrays.copyOf(array, array.length);

        //1.找出逆序区域的边界索引(逆序遍历)

        int startIndex=0;

        for (int i = datas.length - 1; i > 0; i--) {
            if(datas[i]>datas[i-1]){
                startIndex=i;
                break;

            }

        }
        //如果逆序区起始索引为0,说明已经是最大排列,没有下一个数
        if(startIndex==0){

            return null;
        }

        //2.遍历逆序区,交换逆序区前一个数 和逆序区中比他大的最小值。
        //逆序区前一个数
        int beforeData=datas[startIndex-1];

        for (int i = datas.length - 1; i >= startIndex; i--) {

            if(datas[i] >beforeData){
                //交换位置
                datas[startIndex-1]=datas[i];
                datas[i]=beforeData;
                break;
            }

        }

        //逆序区重新排序(由于有序区已经是从大到小的有序序列,所以只要交换首位对应位置即可 转换成正序)

        for (int i=startIndex,j=datas.length-1;i<j;i++,j--){

            int temp=datas[i];

            datas[i]=datas[j];

            datas[j]=temp;

        }

        return  datas;
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值