概述
目的是根据lexicographical排序顺序找到一个给定数字的下一个permutation。如果下一个排列组合不可能,则返回相同的数字。
例如
Input: [1,2,3]
Output: [1,3,2]
Input: [2,1]
Output: [2,1]
Input: [1, 3, 5, 4, 1]
Output: [1, 4, 1, 3, 5]
Input: [1, 3, 2]
Output: [2, 1, 3]
以下是我们的策略
-
从左边开始,找到第一个比右边的数字小的数字。假设这个数字是在索引**"第一 "**处找到的。
-
然后在第一个 索引之后的数组右边部分找到比第一个索引上的数字大的最小的数字。然后用第一个索引上的数字替换这个数字。
-
将数组右边的索引后的部分排序。
程序
下面是同样的程序
package main
import (
"fmt"
"sort"
)
func main() {
nextPermutation([]int{1, 2, 3})
nextPermutation([]int{2, 1})
nextPermutation([]int{1, 3, 5, 4, 1})
nextPermutation([]int{1, 3, 2})
}
func nextPermutation(nums []int) {
numsLen := len(nums)
first := -1
second := -1
for i, j := numsLen-2, numsLen-1; i >= 0; {
if nums[i] < nums[j] {
first = i
second = j
break
} else {
i--
j--
}
}
if !(first == -1) {
smallestGreaterIndex := second
for i := second + 1; i < numsLen; i++ {
if nums[i] > nums[first] && nums[i] < nums[smallestGreaterIndex] {
smallestGreaterIndex = i
}
}
nums[first], nums[smallestGreaterIndex] = nums[smallestGreaterIndex], nums[first]
sort.Slice(nums[second:numsLen], func(i, j int) bool {
return nums[second+i] < nums[second+j]
})
}
fmt.Println(nums)
}
输出
[1 3 2]
[2 1]
[1 4 1 3 5]
[2 1 3]