[LeetCode] 31. Next Permutation

下一个排列。题干就是题意,例子,

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

如果本身已经是降序的了,比如[3, 2, 1],则返回[1, 2, 3]。跑一个正常的例子吧,比如[1, 5, 8, 4, 7, 6, 5, 3, 1],它的下一个排列是[1, 5, 8, 5, 1, 3, 4, 6, 7]。因为input本身就是permutation的一种,又是按字典序,所以发现4后面的五个数字是降序的(7, 6, 5, 3, 1);他的下一个排列是需要找到最小的比4大的数(5)并且将4后面的所有的数字reverse成升序。有了这个思路,所以一开始数组需要用一个i指针从右往左扫,找到第一个不是升序的数字(4),停下;再用第二个指针j从右往左扫第二次,此时找的是第一个比4大的数字,会停在5的位置;将4跟5调换一下位置;

[1, 5, 8, 4, 7, 6, 5, 3, 1] -> [1, 5, 8, 5, 7, 6, 4, 3, 1]

最后再反转后五个数字,从而得到下一个排列。

[1, 5, 8, 5, 7, 6, 4, 3, 1] -> [1, 5, 8, 5, 1, 3, 4, 6, 7]

时间O(n)

空间O(1)

 1 /**
 2  * @param {number[]} nums
 3  * @return {void} Do not return anything, modify nums in-place instead.
 4  */
 5 var nextPermutation = function (nums) {
 6     let i = nums.length - 2;
 7     while (i >= 0 && nums[i] >= nums[i + 1]) {
 8         i--;
 9     }
10     if (i >= 0) {
11         let j = nums.length - 1;
12         while (j >= 0 && nums[j] <= nums[i]) {
13             j--;
14         }
15         swap(nums, i, j);
16     }
17     reverse(nums, i + 1);
18 };
19 
20 var reverse = function (nums, start) {
21     let i = start;
22     let j = nums.length - 1;
23     while (i < j) {
24         swap(nums, i, j);
25         i++;
26         j--;
27     }
28 };
29 
30 var swap = function (nums, i, j) {
31     let temp = nums[i];
32     nums[i] = nums[j];
33     nums[j] = temp;
34 };

猜你喜欢

转载自www.cnblogs.com/aaronliu1991/p/12418303.html