LeetCode第三十一题(下一个排列)

161 阅读1分钟

解释说明: 简单地说,整数数组的下一个排列就是下一个排列形成的整数比当前排列形成的整数的值大且比其他更大值都小。

核心思想: (1)从后往前寻找第一组升序排序的两个整数的组合:【A,B】,其中A < B,以确保后续交换时,下一个排列形成的整数比当前排列形成的整数的值大;(2)由于从整数B到整数数组最后一个整数是降序排序,故从后往前寻找第一个大于整数A的整数C,并让整数C和整数A交换,此时的排列形成的整数的值必然比交换前的排列形成的整数的值大,且从整数B到整数数组最后一个整数仍然是降序排序;(3)由于升序排序的整数值最小,故从整数B到整数数组最后一个整数改为升序排序即可。

注意: 不存在一个字典序更大的排列,即整数数组的当前排列为降序排列,形成的整数的值最大,此时,下一个排列就是将当前排列改为升序排列。

class Solution {
    public void nextPermutation(int[] nums) {
        int posA = nums.length - 2, posB = nums.length - 1, posC = nums.length - 1;
        while(posA != -1 && nums[posA] >= nums[posB]){//从后往前寻找第一组升序排序的两个整数的组合:【A,B】,其中A < B
            posA -= 1;
            posB -= 1;
        }
        if(posA != -1){//存在一个字典序更大的排列,即存在比当前排列形成的整数的值大的下一个排列
            while(nums[posC] <= nums[posA])//从后往前寻找第一个大于整数A的整数C
                posC--;
            swap(nums, posA, posC);//让整数C和整数A交换
        }
        arrayInc(nums, posB);//从整数B到整数数组最后一个整数改为升序排序
    }
    //交换整数A和整数C
    public void swap(int[] nums, int posA, int posC){
        int tmp = nums[posA];
        nums[posA] = nums[posC];
        nums[posC] = tmp;
    }
    //升序排序(从整数B到整数数组最后一个整数)
    public void arrayInc(int[] nums, int posB){
        int start = posB, end = nums.length - 1;
        while(start < end){
            swap(nums, start, end);
            start++;
            end--;
        }
    }
}