LeetCode——31.下一个排列

本次博客,我将记录LeetCode第31题,下一个排列

31. 下一个排列

image

题目分析:

首先,我们以1 2 3为例,其全排列按照字典序就是123 132 213 231 312 321,那么213的下一个排列就是231,本题就是要找到这样一个序列

解题思路:
首先,对于已经处在字典序最大的那个序列,我们只要将其判断出来并进行从小到大排序即可

对于需要寻找下一个排列的序列,我们可以这样理解:

所谓的下一个排列,要满足以下两点要求:
1.下一个排列比当前排列的字典序要大
2.下一个排列的增幅须保证最小

step1:那么从后往前遍历数组(相较于从前往后改变元素,这样可以保证操作后的增幅更小),如果此时是升序排列(从后往前),那么不去管他(因为此时交换会使得字典序变小),一旦发现出现降序,即nums[i]<nums[i+1],这时就停止遍历,因为我们已经找到了需要交换的位置,记为nums[i]

step2:为了满足交换后的序列的字典序增幅最小,我们再次从后往前遍历数组(还记得前面忽略的升序序列吗?)找到第一个nums[j]>nums[i]并交换i和j上的元素,退出遍历

step3:最后,那一段从后往前是升序的序列(从前往后便是降序),我们对其进行revise,也就是翻转顺序,最终,我们得到了“下一个排列”

图解举例

image

java代码

class Solution {
        public static void swap(int[] a,int i,int j){
        if(i!=j) {
            a[j] ^= a[i];
            a[i] ^= a[j];
            a[j] ^= a[i];
        }
    }
    public static void reverse(int[] a,int i){
        int L=i,R=a.length-1;
        while(L<R){
            swap(a,L,R);
            L++;
            R--;
        }
    }
    public static void nextPermutation(int[] nums){
        boolean flag=true;
        int i,j;
        for(i=nums.length-2;i>=0;i--){
            if(nums[i]<nums[i+1]){
                flag=false;
                break;
            }
        }
        if(flag){
            Arrays.sort(nums);
            return;
        }
        for(j=nums.length-1;j>=0;j--){
            if(nums[j]>nums[i]){
                swap(nums,i,j);
                break;
            }
        }
        reverse(nums,i+1);
    }
}

本文完

posted @ 2022-09-30 17:23  Sky6634  阅读(73)  评论(0)    收藏  举报