[LeetCode-Golang] 31. 下一个排列

题目

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
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%的用户

猜你喜欢

转载自www.cnblogs.com/nini-skyrim/p/12677352.html