1)逆序寻找第一个下降点(下降点之后的序列已经是完全逆序的)
2-A)如果完全逆序,完全反转即可返回
2-B)非完全逆序,寻找第一个大于下降点的数up (up 就是下一个要放到前面的)
3)swap(down, up)
4) reverse(down + 1, len-1) (后面调整为正序,才是下一个要找的)
/**
* 字母序-升序-下一个排列
1)逆序寻找第一个下降点(下降点之后的序列已经是完全逆序的)
2-A)如果完全逆序,完全反转即可返回
2-B)非完全逆序,寻找第一个大于下降点的数up (up 就是下一个要放到前面的)
3)swap(down, up)
4) reverse(down + 1, len-1) (后面调整为正序,才是下一个要找的)
O(N)
**/
func nextPermutation(nums []int) {
if nums == nil || len(nums) <= 0 {
return
}
length := len(nums)
// find the first fall point in reverse order
down := length - 1
for ; down > 0; down-- {
if nums[down] > nums[down-1] {
break
}
}
// totally reserse
if down == 0 {
reverse(nums, 0, length - 1)
return
}
down--
// find the first number bigger than the fall point after the fall point
up := down + 1
for ; up < length - 1; up++ {
if nums[up + 1] <= nums[down] {
break
}
}
// swap down up point
nums[down], nums[up] = nums[up], nums[down]
// reverse (down + 1 to up)
reverse(nums, down + 1, length - 1)
}
func reverse(nums []int, start int, end int) {
for ; start < end; {
nums[start], nums[end] = nums[end], nums[start]
start++
end--
}
}