问题描述:给定一个数字,求全排列下一个数字,如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; } }