【LeetCode】31.下一个排列

[LeetCode]31.下一个排列

题目

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

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

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

示例 1

输入:nums = [1,2,3]
输出:[1,3,2]

示例 2

输入:nums = [3,2,1]
输出:[1,2,3]

解析

最好自己在纸画一下4个数的字典排序,就会发现下一队列如下规律

  1. 第一个队列升序排序
  2. 从右往前交换,当后面数列整个倒序时,需要往前升一位
  3. 往前升一位后,后面的队列是升序排列
  4. 需要升序情况(假设 i 需要升一位,k 是所需的数字)
    1. 这个时候[i + 1, n]倒序排列
    2. 因为这个时候[i + 1, n]倒序,替换i , k位置,并把队列反转就是需要的下一队列
  • 难点
  1. 不能使用额外空间
  • 算法流程
  1. 特判
    1. 数组长度小于2 : 直接返回
    2. 数组长度 == 2 或者 倒数第二位 小于 倒数第一 : 交换最后两位数即可
  2. 找到需要升位的位置pointer
  3. 左右指针遍历
    1. 右边第一个大于nums[i]或左边最后一个大于nums[i]即需要升位的数字
    2. 替换左右指针位置(反转队列)

源码

from typing import List, Literal


class Solution:

    def nextPermutation(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """

        if not nums or len(nums) <= 1:
            return

        length = len(nums)

        if length == 2 or nums[length - 2] < nums[length - 1]:
            nums[length - 2], nums[length - 1] = nums[length - 1], nums[length - 2]
            return

        pointer = length - 3
        while pointer >= 0:
            if nums[pointer] < nums[pointer + 1]:
                break
            pointer = pointer - 1

        left = pointer + 1
        right = length - 1
        current_val = nums[pointer] if pointer >= 0 else 101
        is_swap = False

        while left <= right:

            if not is_swap and nums[right] > current_val:
                nums[pointer], nums[right] = nums[right], nums[pointer]
                is_swap = True

            if not is_swap and nums[left] > current_val and nums[left + 1] <= current_val:
                nums[left], nums[pointer] = nums[pointer], nums[left]
                is_swap = True

            nums[left], nums[right] = nums[right], nums[left]
            left += 1
            right -= 1
            pass

引用

LeetCode - 31.下一个排列

源码 - GitHub

posted @   WilsonPan  阅读(95)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示