website/content.en/ChapterFour/0001~0099/0031.Next-Permutation.md
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such an arrangement is not possible, it must rearrange it as the lowest possible order (i.e., sorted in ascending order).
The replacement must be in place and use only constant extra memory.
Example 1:
Input: nums = [1,2,3]
Output: [1,3,2]
Example 2:
Input: nums = [3,2,1]
Output: [1,2,3]
Example 3:
Input: nums = [1,1,5]
Output: [1,5,1]
Example 4:
Input: nums = [1]
Output: [1]
Constraints:
1 <= nums.length <= 1000 <= nums[i] <= 100Implement the function to get the next permutation. The algorithm needs to rearrange the given sequence of numbers into the next greater permutation in lexicographical order. If there is no next greater permutation, rearrange the numbers into the smallest permutation (i.e., sorted in ascending order). The modification must be done in place, and only constant extra space is allowed.
i in nums[i] such that nums[i] < nums[i+1]. At this point, the smaller number is nums[i], and [i+1, n) must be a descending interval. Step 2: if such an i is found, then in the descending interval [i+1, n), search from back to front for the first j such that nums[i] < nums[j]. At this point, the larger number is nums[j]. Step 3: swap nums[i] and nums[j]. At this point, the interval [i+1, n) must be in descending order. Finally, swap the elements in the interval [i+1, n) in place to make it ascending; there is no need to sort this interval.i can be found in the first step, it means the current sequence is already the largest permutation. Then the third step should be executed directly to generate the smallest permutation.package leetcode
// Solution 1
func nextPermutation(nums []int) {
i, j := 0, 0
for i = len(nums) - 2; i >= 0; i-- {
if nums[i] < nums[i+1] {
break
}
}
if i >= 0 {
for j = len(nums) - 1; j > i; j-- {
if nums[j] > nums[i] {
break
}
}
swap(&nums, i, j)
}
reverse(&nums, i+1, len(nums)-1)
}
func reverse(nums *[]int, i, j int) {
for i < j {
swap(nums, i, j)
i++
j--
}
}
func swap(nums *[]int, i, j int) {
(*nums)[i], (*nums)[j] = (*nums)[j], (*nums)[i]
}
// Solution 2
// [2,(3),6,5,4,1] -> 2,(4),6,5,(3),1 -> 2,4, 1,3,5,6
func nextPermutation1(nums []int) {
var n = len(nums)
var pIdx = checkPermutationPossibility(nums)
if pIdx == -1 {
reverse(&nums, 0, n-1)
return
}
var rp = len(nums) - 1
// start from right most to leftward,find the first number which is larger than PIVOT
for rp > 0 {
if nums[rp] > nums[pIdx] {
swap(&nums, pIdx, rp)
break
} else {
rp--
}
}
// Finally, Reverse all elements which are right from pivot
reverse(&nums, pIdx+1, n-1)
}
// checkPermutationPossibility returns 1st occurrence Index where
// value is in decreasing order(from right to left)
// returns -1 if not found(it's already in its last permutation)
func checkPermutationPossibility(nums []int) (idx int) {
// search right to left for 1st number(from right) that is not in increasing order
var rp = len(nums) - 1
for rp > 0 {
if nums[rp-1] < nums[rp] {
idx = rp - 1
return idx
}
rp--
}
return -1
}