【JS每日一算法】25.下一个排列(快排)

3,633 阅读3分钟

给定一个整数数组,将其按顺序组合为一个整数。如何将这些元素重新排列组合得到下一个更大的整数。

例如:[1,2,3]按顺序组合为整数123,重新排列组合后下一个更大的数为132即为[1,3,2],如果无法得到一个更大的整数,则组合为最小的整数。

给你一个整数数组 nums ,按上述条件返回nums的下一个排列(必须 原地 修改,只允许使用额外常数空间)。

更多JS版本题解点击链接关注该仓库👀

/**
 * @description: 快速排序方法   TC:O(n)  SC:O(1)
 * @author: JunLiangWang
 * @param {*} nums
 * @return {*}
 */
function quickSort(nums){
    /**
     * 我们希望下一个数比当前数大,因此只需要将后面的「大数」与前面的「小数」交换,就能得到一个更大的数。
     * 比如123456,将5和6交换就能得到一个更大的数123465。我们还希望下一个数增加的幅度尽可能的小,这样才
     * 满足“比当前数大的下一个数“的要求。为了满足这个要求,我们需要:在尽可能靠右的低位进行交换,需要从后
     * 向前查找将一个尽可能小的「大数」与前面的「小数」交换。比如123465,下一个排列应该把5和4交换而不是把
     * 6和4交换将「大数」换到前面后,需要将「大数」后面的所有数重置为升序,升序排列就是最小的排列。以123465
     * 为例:首先按照上一步,交换 5 和 4,得到 123564;然后需要将 5 之后的数重置为升序,得到 123546。
     * 显然 123546 比 123564 更小,123546 就是 123465 的下一个排列
     */

    // 如果数组元素少于1,则直接返回即可
    if(nums.length<=1)return nums;

    /**
     * @description: 交换数组两个元素位置
     * @author: JunLiangWang
     * @param {*} i   元素1位置
     * @param {*} j   元素2位置
     * @return {*}
     */
    function swap(i,j)
    {
        let temp=nums[i];
        nums[i]=nums[j];
        nums[j]=temp;
    }

    // 初始化更小值指针为最后一个元素
    let smallerPoint=nums.length-2;
    // 从右向左遍历数组,并找到违反降序的元素,此元素则为需要交换的元素,
    // 如果数组元素全为降序,则该指针值为-1
    while(smallerPoint>=0&&nums[smallerPoint]>=nums[smallerPoint+1])smallerPoint--;
    // 如果数组元素全为降序,此时将smallerPoint赋值为0
    // 后续需要将数组元素全变为升序
    if(smallerPoint==-1)
    {
        smallerPoint=0;
    }
    // 否则需要在已遍历的元素中找到比该元素大,且最接近该元素的数进行交换,
    // 并将该元素后续所有元素变为升序
    else
    {
        // 初始化更大的元素为数组最后一个元素
        let biggerPoint=nums.length-1;
        // 找到比该元素大的元素,此处之所以不需要判断biggerPoint>smallerPoint
        // 因为进入该条件总会有一个比smallerPoint所指元素大的元素
        while(nums[biggerPoint]<=nums[smallerPoint])biggerPoint--;
        // 进行交换
        swap(smallerPoint,biggerPoint);
        // 将smallerPoint+1,后续需要将该元素后续所有元素变为升序
        smallerPoint++;
    }

    let tempPoint=nums.length-1;
    // 从smallerPoint到nums的最后一个元素,两两交换元素,将
    // 该区间降序变为升序。如果数组全为降序,则smallerPoint
    // 等于0,则是将数组全部元素从降序变为升序
    while(smallerPoint<tempPoint)
    {
        swap(smallerPoint,tempPoint);
        smallerPoint++;
        tempPoint--;
    }
}