31 Next Permutation

将一组数打乱顺序,所有不同顺序的排列的集合。对于一个任意序列,最小的排列是增序,最大的排列是减序。最小的排列起始数目最小,最大的排列起始数目最大。要找下一个大的全排列,就是找最大的降序的。

  • Runtime: 88 ms, faster than 70.72%
  • Memory Usage: 37.4 MB, less than 61.81%

对当前排列从后向前扫描,找到一对为升序的,记录为i和j (i > j)。如果不存在这样一对为升序的相邻元素,所有排列已找到,算法结束。否则,重新对当前排列从后向前扫描,找到第一个大于j的元素k,交换j 和k,然后对从j开始到结束的子序列反转,此时得到的新排列就是写一个字典序排列。这种方式实现得到的所有排列是按字典序有序的,这也是C++STL 算法next_permutation的思想。

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var nextPermutation = function(nums) {
    let len = nums.length
    var j
    for(var i = len - 1; i > 0; i--) {
        if(nums[i - 1] < nums[i]) {
            j = i - 1
            break
        }
    }
    if(j === undefined) return nums.reverse()
    for(var k = len - 1; k > j; k--){
        if(nums[k] > nums[j]) {
            swap(nums, k, j)
            break
        }
    }
    let s = nums.slice(i).reverse()
    nums.splice(i, len - 1, ...s)
    return nums
};

var swap = function (nums, m, n) {
    let temp = nums[m]
    nums[m] = nums[n]
    nums[n] = temp
}

你可能感兴趣的:(31 Next Permutation)