diff --git a/problems/0031.下一个排列.md b/problems/0031.下一个排列.md index 05321a9a..46568fae 100644 --- a/problems/0031.下一个排列.md +++ b/problems/0031.下一个排列.md @@ -132,6 +132,52 @@ class Solution { ## JavaScript ```js +//卡尔的解法(吐槽一下JavaScript的sort和其他语言的不太一样,只想到了拷贝数组去排序再替换原数组来实现nums的[i + 1, nums.length)升序排序) +var nextPermutation = function(nums) { + for(let i = nums.length - 1; i >= 0; i--){ + for(let j = nums.length - 1; j > i; j--){ + if(nums[j] > nums[i]){ + [nums[j],nums[i]] = [nums[i],nums[j]]; // 交换 + // 深拷贝[i + 1, nums.length)部分到新数组arr + let arr = nums.slice(i+1); + // arr升序排序 + arr.sort((a,b) => a - b); + // arr替换nums的[i + 1, nums.length)部分 + nums.splice(i+1,nums.length - i, ...arr); + return; + } + } + } + nums.sort((a,b) => a - b); // 不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 +}; + +//另一种 +var nextPermutation = function(nums) { + let i = nums.length - 2; + // 从右往左遍历拿到第一个左边小于右边的 i,此时 i 右边的数组是从右往左递增的 + while (i >= 0 && nums[i] >= nums[i+1]){ + i--; + } + if (i >= 0){ + let j = nums.length - 1; + // 从右往左遍历拿到第一个大于nums[i]的数,因为之前nums[i]是第一个小于他右边的数,所以他的右边一定有大于他的数 + while (j >= 0 && nums[j] <= nums[i]){ + j--; + } + // 交换两个数 + [nums[j], nums[i]] = [nums[i], nums[j]]; + } + // 对 i 右边的数进行交换 + // 因为 i 右边的数原来是从右往左递增的,把一个较小的值交换过来之后,仍然维持单调递增特性 + // 此时头尾交换并向中间逼近就能获得 i 右边序列的最小值 + let l = i + 1; + let r = nums.length - 1; + while (l < r){ + [nums[l], nums[r]] = [nums[r], nums[l]]; + l++; + r--; + } +}; ``` -----------------------