31. Next Permutation

1. Description

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such an arrangement is not possible, it must rearrange it as the lowest possible order (i.e., sorted in ascending order).
The replacement must be in place and use only constant extra memory.
Example 1:

Input: nums = [1,2,3]
Output: [1,3,2]

Example 2:

Input: nums = [3,2,1]
Output: [1,2,3]

Example 3:

Input: nums = [1,1,5]
Output: [1,5,1]

Example 4:

Input: nums = [1]
Output: [1]

Constraints:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100

2. My code

/**
 Do not return anything, modify nums in-place instead.
 */
function nextPermutation(nums: number[]): void {
    const len=nums.length;
    let abruptPointIndex=-1; // 转折点,即不是升序(从右到左排列)
    let i=len;
    while(--i){
        if(nums[i-1]<nums[i]){
            abruptPointIndex=i-1;
            break;
        }
    }
    if(abruptPointIndex===-1){
        // 意味着没有找到转折点,数组从右到左的序列都是升序,直接逆转排列
        nums.reverse();
    }else{
        // 从转折点后面的数组,寻找到刚好比转折点大的那一个数字,这里代指 x,将 x 和转折点交换顺序
        // 我总是把转折点后面的第一个数当成 x,几次提交错了却浑然不知
        let secondMaxPoint=nums[abruptPointIndex];
        let secondMaxPointIndex=abruptPointIndex+1;
        for(let i=len-1;i>abruptPointIndex;i--){
            if(nums[i]>secondMaxPoint){
                secondMaxPoint=nums[i];
                secondMaxPointIndex=i;
                break;
            }
        }
        const temp=nums[abruptPointIndex];
        nums[abruptPointIndex]=secondMaxPoint;
        nums[secondMaxPointIndex]=temp;
        // 将转折点后的数组按照从左到右的升序排列,保证后面数组为最小的排序序列
        const tempArr=nums.splice(abruptPointIndex+1);
        tempArr.sort((a,b)=>a-b);
        Array.prototype.push.apply(nums,tempArr);
    }
};

3. Summary

题目属实有点抽象了,考验了我们对与排序的理解。这里非常感谢下一个排列算法详解:思路+推导+步骤,看不懂算我输!这篇文章对我的启发。通过趋势图让我对排序有了进一步的认知,我以前的认知都是数字化的,加上这个图形化,真的受益匪浅。

原文地址:https://www.cnblogs.com/panshaojun/p/15504181.html