zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    《团队-爬取豆瓣Top250-团队一阶段互评》
    团队-爬虫豆瓣top250项目-开发文档
    结对总结
    课后作业-阅读任务-阅读提问-2
    2017-10-06-构建之法:现代软件工程-阅读笔记
    结对-结对编项目贪吃蛇-开发过程
    团队-爬取豆瓣电影TOP250-开发环境搭建过程
    个人-GIT使用方法
    课后作业-阅读任务-阅读提问-1
    课后作业-阅读任务-阅读笔记-1
  • 原文地址:https://www.cnblogs.com/WilsonPan/p/14463337.html
Copyright © 2011-2022 走看看