leetcode_31_下一个排列

31. 下一个排列

题目描述
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

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

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

分析:首先明白,下一个排列一定是比当前的数字大的,
如1 2 3 4 6 5 7 --> 1 2 3 4 6 7 5 ,一个数想要变大,而且是最小程度的变大,那么就会想到,把个位数变大,但是题目要求的中每个数位的数字和个数是固定的,所以只能通过交换位置把低位上的较大的数和高位的较小的数交换,把数变大,那么从后往前,把较大的数换到前面去,这个数就会变大,想要最接近的变大,硬核:根据维基百科下一个排列定义:
在这里插入图片描述
翻译后步骤如下:
1.先找出最大的索引 k 满足 nums[k] < nums[k+1],如果不存在,就翻转整个数组;
2.再找出另一个最大索引 l 满足 nums[l] > nums[k];
3.交换 nums[l] 和 nums[k];
4.最后翻转 nums[k+1:]。
参考leetcode 的powcai 大佬的方法

def nextPermutation(nums):
    """
    :type nums: List[int]
    :rtype: None Do not return anything, modify nums in-place instead.
    """
    def nums_reverse(start,end):
        while start < end:
            nums[start],nums[end] = nums[end],nums[start]
            start += 1 
            end -= 1 
    ans = []
    n = len(nums)
    if n <= 1 :
        return nums
    firstindex  = -1 
    for i in range(n-2,-1,-1):
        if nums[i] < nums[i+1]:
            firstindex = i
            break
    print("firstindex",firstindex)
    if firstindex == -1 :
        nums_reverse(0,n-1)
        print(nums)
        return 
    secondindex = -1 
    for j in range(n-1,firstindex,-1):
        if nums[j] > nums[firstindex]:
            secondindex = j
            break
    print(firstindex,secondindex)
    nums[firstindex],nums[secondindex] = nums[secondindex],nums[firstindex]
    nums_reverse(firstindex + 1 ,n-1)
    print(nums)
        
nums  = [3,2,1]
# 4 2 0 2 3 2 0 ==》  4 2 0 3 0 2 2  
nextPermutation(nums)

题目总结:数组的原地更改指的是数组的内存地址不变,不能直接申请一块内存直接创建一个新数组,哪怕是数组名字一样,内存地址也是不同的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值