leetcode刷题之下一个排列

73 阅读1分钟

1. 题目描述

无论如何,给了一堆数(某一堆数的排列中的一种),要求你找出这对数的下一个最大的排列是什么? 举个例子:123 -> 132, 135 -> 153, 123456234 -> 123456324

2. 解题思路

分成三个步骤:

  1. 从后往前找出第一个升序的位置
  2. 将该位置与下一个位置交换顺序
  3. 后面的逆序排列

3. 具体题目

  • 第 31 题

image.png

按照前面的思路,具体的实现代码如下:

/** 
* @param {number[]} nums 
* @return {void} Do not return anything, modify nums in-place instead. 
*/ 
var nextPermutation = function(nums) { 
    const swap = (i,j) => { 
        let temp = nums[i]; 
        nums[i] = nums[j]; 
        nums[j] = temp; 
    }; 
    const reverse = (i) => { 
        let left = i; 
        let right = nums.length - 1; 
        while(left < right) { 
            swap(left, right); 
            left++; 
            right--; 
        } 
    }; 
    
    let i = nums.length - 2; 
    while(i >= 0 && nums[i] >= nums[i + 1]) { 
        i--; 
    } 
    if(i >= 0) { 
        let j = nums.length - 1; 
        while(j >= 0 && nums[i]>= nums[j]) { 
            j--; 
        } 
        swap(i, j); 
    } 
    reverse(i + 1);
};
  • 第 556 题:

image.png

这个题目和上一个题目本质上是相同的,具体的实现代码如下:

/**
 * @param {number} n
 * @return {number}
 */
var nextGreaterElement = function(n) {
    const nStr = n.toString().split('');
    const len = nStr.length;
    let pos = -1

    const  swap = (i, j) => {
        let temp = nStr[i];
        nStr[i] = nStr[j];
        nStr[j] = temp;
    }

    const reverse = (i) => {
        let left = i, right = len - 1;
        while(left < right) {
            swap(left, right);
            left++;
            right--;
        }
    }

    for(let i = len - 1; i >= 0; i--) {
        if(i > 0 && nStr[i - 1] < nStr[i]) {
            pos = i - 1;
            break;
        }
    }

    if(pos === -1) {
        return -1;
    }

    for(let i = len - 1; i >= 0; i--) {
        if(nStr[i] > nStr[pos]) {
            swap(i, pos);
            break;
        }
    }

    reverse(pos + 1);

    return parseInt(nStr.join('')) <= Math.pow(2, 31) - 1 ? parseInt(nStr.join('')) : -1;
};