31.下一个排列
31.下一个排列
题解
题目:给一个数组,可以看出一个数字,求大于该数字 并且 最贴近该数字 的数,特别的如果这个数是降序,则返回升序即可
思路:
变大的幅度尽可能小
1. 将一个左边的「较小数」与一个右边的「较大数」交换
2. 让这个「较小数」尽量靠右,而「较大数」尽可能小
3. 这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小
- 我们希望找到一个新序列,大于当前序列,并且变大的幅度尽可能的小
- 以4,5,2,6,3,1为例
- 从后向前找到第一个
nums[i] < nums[i+1] ,这样[i+1,n] 是降序 nums[i]为[较小数]---------2 [i+1,n] 从后往前找第一个nums[j] > nums[i] ,称nums[j]为[较大数]---------3- 交换nums[i]和nums[j],此时
[i+1,n] 还是降序 - 例子成为了4,5,3,6,2,1
- 将
[i+1,n] 升序-----4,5,3,1,2,6 - 答案就出来了
代码
func nextPermutation(nums []int) {
i := len(nums) - 2
j := len(nums) - 1
for ; i >= 0; i-- {
if nums[i] < nums[i+1] {
break
}
}
if i >= 0 {
for ; j >= i+1; j-- {
if nums[i] < nums[j] {
break
}
}
nums[i], nums[j] = nums[j], nums[i]
}
sort.Ints(nums[i+1:])
}
|