求下一个排列数

问题描述:给定一个数字,求全排列下一个数字,如21534,下一个比它大的数字是23145

算法分析:逐位考察哪个能增大,一个数右面有比它大的数存在,它就能增大,那么最后一个能增大的数是x=1,1应该增大到多少?增大到它右面比它大的最小的数y=3,应该变为23xxx,显然,xxx应由小到大排:145,最终得到23145

整理以上,步骤是后找,小大,交换,翻转

后找:字符串中最后一个升序的位置i,即:S[k]>S[k+1](k>i),S[i]<S[i+1];

查找(小大):S[i+1...N-1]中比Ai大的最小值Sj

交换:Si,Sj;

翻转:S[i+1...N-1]

代码:

public static void main(String[] args) {
    Integer[] array = new Integer[5];
    array[0] = 2;
    array[1] = 1;
    array[2] = 5;
    array[3] = 4;
    array[4] = 3;
    getNextPermutation(array);
    for(Integer i : array){
        System.out.println(i);
    }
}

public static void getNextPermutation(Integer[] array){
    //后找
    int i = array.length - 2;
    while(i >= 0 && array[i] >= array[i+1]){
        i--;
    }
    //说明当前数组中存放的拼接起来就是最大的数,不存在比它还大的数
    if(i<0){
        return;
    }
    //从后找,找到第一个比array[i]大的数
    int j = array.length - 1;
    while(array[j] <= array[i]){
        j--;
    }
    Integer temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    Integer[] temp2= Arrays.copyOfRange(array, i+1,array.length);
    reverseStr(temp2);
    for(int k = i+1;k<array.length;k++){
        array[k] = temp2[k-i-1];
    }
}

/**
 * 翻转字符串
 * @param array
 * @return
 */
public static void reverseStr(Integer ... array){
    int from = 0;
    int to = array.length-1;
    Integer temp;
    while(from < to){
        temp = array[from];
        array[from++] = array[to];
        array[to--] = temp;
    }
}

猜你喜欢

转载自blog.csdn.net/junglerofchina/article/details/79477875