下一个排列。题干就是题意,例子,
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 };