题目
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-permutation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
见代码注释(切片类型是引用传递)
代码
func nextPermutation(nums []int) { if len(nums) == 0 || len(nums) == 1 { return } // 从右往左找到第一个nums[i]>[i-1] i := len(nums)-1 for i > 0 && nums[i] <= nums[i-1] { i-- } // 如果已经不存在下一个更大的排列,翻转数组可得最小的排列 if i == 0 { reverse(nums) return } // 如果存在下一个更大的排列,由于nums[i]>nums[i-1]&&nums[i:]为降序排列,所以nums[i:]从后往前寻找第一个比nums[i-1]大的数,进行交换 for j := len(nums)-1; j >= i; j-- { if nums[i-1] < nums[j] { nums[i-1], nums[j] = nums[j], nums[i-1] // 交换后,翻转仍旧降序排列的nums[i]即可 reverse(nums[i:]) return } } } func reverse(nums []int) { i, j := 0, len(nums)-1 for i < j { nums[i], nums[j] = nums[j], nums[i] i++ j-- } return }
复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
执行结果
执行用时 :0 ms, 在所有 Go 提交中击败了100.00% 的用户
内存消耗 :2.5 MB, 在所有 Go 提交中击败了100.00%的用户