Leetcode(Top100)----31. 下一个排列

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

class Solution {
     
    //标签:数组
    public void nextPermutation(int[] nums) {
     
        if(nums.length < 2){
     
            return ;
        }
        int i = nums.length - 2; //倒数第二个元素
        int j = nums.length - 1; //倒数第一个元素
        while(i>=0 && nums[i] >= nums[i+1]){
      //寻找一个升序对,记得加=,相同的两个元素不是升序对
            i--;
        }
        if(i>=0){
      //若整个数组不是降序的,则寻找大数
            while(j>=i+1 && nums[j]<=nums[i]){
     
                    j--;
                }
                int temp = nums[i];
                nums[i] = nums[j];
                nums[j] = temp;
        }
		//对数组进行降序,无论数组原本是降序的还是有下一个排列的
        int L = i+1;
        int R = nums.length - 1;
        while(L < R){
     
            int temp2 = nums[L];
            nums[L] = nums[R];
            nums[R] = temp2;
            L++;
            R--;
        }
    }
}

解题思路:
分析:题目意思是寻求下一个相邻的比其大的数,若采用暴力法则时间复杂度为O(n!),这是远远不行的
算法推导:

  • 既然寻求一个更大的数,只要将一个比较大的位数置换到前面位即可
  • 同时还要紧邻目前这个数的,那么尽量在数组的最右边进行第一步,进行元素的交换
  • 再对大数后面的数排序,那么得到的数组就是下一个排列

算法过程

  • 第一步,从数组最右边开始寻找一个升序对[i,i+1],说明[i+1,end)都是降序的
  • 第二步,从数组最右边寻找到第一个大于nums[i]的大数nums[j],然后交换
  • 第三步,对i+1之后的部分数组(降序)排序为升序数组(由于是降序的,所以头尾指针所指元素两两交换,再内移指针),若数组本身是降序的,则直接排序

你可能感兴趣的:(Leetcode,数组)