/*
* @lc app=leetcode id=31 lang=javascript
*
* [31] Next Permutation
*/
function reverseRange(A, i, j) {
while (i < j) {
const temp = A[i];
A[i] = A[j];
A[j] = temp;
i++;
j--;
}
}
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var nextPermutation = function (nums) {
// 时间复杂度O(n) 空间复杂度O(1)
if (nums == null || nums.length <= 1) return;
let i = nums.length - 2;
// 从后往前找到第一个降序的,相当于找到了我们的回溯点
while (i > -1 && nums[i + 1] <= nums[i]) i--;
// 如果找了就swap
if (i > -1) {
let j = nums.length - 1;
// 找到从右边起第一个大于nums[i]的,并将其和nums[i]进行交换
// 因为如果交换的数字比nums[i]还要小肯定不符合题意
while (nums[j] <= nums[i]) j--;
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
// 最后我们只需要将剩下的元素从左到右,依次填入当前最小的元素就可以保证是大于当前排列的最小值了
// [i + 1, A.length -1]的元素进行反转
reverseRange(nums, i + 1, nums.length - 1);
};
Python3 Code:
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
i = len(nums) - 2
while i >= 0 and nums[i] >= nums[i + 1]:
i -= 1
if i >= 0:
j = len(nums) - 1
while j >= 0 and nums[i] >= nums[j]:
j -= 1
nums[i], nums[j] = nums[j], nums[i]
left, right = i + 1, len(nums) - 1
while left < right:
nums[left], nums[right] = nums[right], nums[left]
left += 1
right -= 1
CPP Code:
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int i = nums.size() - 2, j = nums.size() - 1;
while (i >= 0 && nums[i] >= nums[i + 1]) --i;
if (i >= 0) {
while (j > i && nums[j] <= nums[i]) --j;
swap(nums[i], nums[j]);
}
reverse(nums.begin() + i + 1, nums.end());
}
};