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

  • 相关阅读:
    中国剩余定理
    hdu1808-Halloween treats(抽屉原理)
    快速幂算法
    因子和与因子个数
    乘性函数
    HDU 2669 Romantic (扩展欧几里得定理)
    扩展欧几里得算法
    Bi-shoe and Phi-shoe(欧拉函数)
    欧拉函数
    [51nod]1284 2 3 5 7的倍数(容斥原理)
  • 原文地址:https://www.cnblogs.com/WilsonPan/p/14463337.html
Copyright © 2011-2022 走看看