字典序生成排列

比较粗暴,根据《离散数学及其应用》的伪代码直接写的。

public class GeneratingPermutation {
    public static void main(String[] args) {
        System.out.println(genPerm("123"));
        System.out.println(genPerm("243541"));
    }
    /**
     * 给定一个字符串
     * 按照字典顺序生成下一个最大排列
     *
     * 参考思路:
     * 从字符串的最后两位开始往前查找
     * 直到找到一对字符,前一个小于后一个    (a[j] < a[j+1])
     * 此时说明a[j]可以与后面大于它的字符交换位置,生成更大的字符
     * 如243541,从后往前找,找到的第一对前一个小于后一个的是{3,5}
     * 要生成更大的字符串,3可以与其后面的[5和4]交换位置
     * 如何选择呢?答案是找到大于3的最小整数,那就是4.
     * 与4交换位置得到的是244[531]
     * 交换完位置之后,其后面字符串肯定是个递减序列,如上的531
     * 我们还需要再次对其进行倒置变为递增,以符合[最小]大于原字符串的排列。
     * 即531排序成135
     * 得到最后字符串便是244135
     * */
    public static String genPerm(String str) {
        char[] strs = str.toCharArray();
        int n = strs.length;
        int j = n - 2;

        //查找aj < a[j+1]时j的位置
        while (strs[j] > strs[j+1]) {
            j--;
        }
        //查找a[j]右边大于a[j]的最小字符
        int k = n - 1;
        while (strs[j] > strs[k]) {
            k--;
        }
        //交换两个字符的位置
        char t = strs[j];
        strs[j] = strs[k];
        strs[k] = t;
        //将后面递减顺序的字符串排成递增顺序
        int s = j + 1;
        int r = n - 1;
        while (r > s) {
            t = strs[s];
            strs[s++] = strs[r];
            strs[r--] = t;
        }

        str = new String(strs);
        return str;
    }
}

END

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值