实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
分析
首先,我们来分析题目的要求内容,我们先来理解什么是下一个排列,算法需要给定数字序列排成更大的一个数字,在给定例子之中,123 是1,2,3,这三个数字之中能给定的最小的数字,所以下一个是十位和个位上的调换,而321是最大的数字,所以下个更大的排列不存在,变为最小的排列。
给定一个例子,以12345为例,应该有12345,12354,12435,12453,123534.。。。。。。54321这样的排列,所以我能只需要从后遍历,遇到有比前位更大的数字,则将两数抵换,需要注意的是,我们换了最低的数字后,要将这个数后面的数字按升序排好,这样才是下一个排列,具体代码如下:
func nextPermutation(nums []int) {
if len(nums) <= 1 {
return
}
//先行定义i为前面那个数字,j,k为交换数字和排列交换后的排列升序
i, j, k := len(nums)-2, len(nums)-1, len(nums)-1
tmp := 0
// 先行找到是否有前数大于后数的情况,并找出最前面的一位数
for i >= 0 && nums[i] >= nums[j] {
i--
j--
}
if i >= 0 {
//找到有后数大于前数
for nums[i] >= nums[k] {
k--
}
// swap A[i], A[k]
tmp = nums[i]
nums[i] = nums[k]
nums[k] =tmp
}
// 排列
for i, j := j, len(nums)-1; i < j; i, j = i+1, j-1 {
tmp = nums[i]
nums[i] = nums[j]
nums[j] = tmp
}
}