Leetcode31. 下一个排列

目录

    • 一、题目描述:
    • 二、解决思路和代码
      • 1. 解决思路
      • 2. 代码

一、题目描述:

整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。

例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。
类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。
而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。
给你一个整数数组 nums ,找出 nums 的下一个排列。

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

  1. 示例 1:

    • 输入:nums = [1,2,3]
    • 输出:[1,3,2]
  2. 示例 2:

    • 输入:nums = [3,2,1]
    • 输出:[1,2,3]
  3. 示例 3:

    • 输入:nums = [1,1,5]
    • 输出:[1,5,1]
  • 提示:
    • 1 ≤ n u m s . l e n g t h ≤ 100 1 \leq nums.length \leq 100 1nums.length100
    • 0 ≤ n u m s [ i ] ≤ 100 0 \leq nums[i] \leq 100 0nums[i]100

二、解决思路和代码

1. 解决思路

  • 分析:如果完全理解题目的意思,这道题还是很简单的。这里找一个长一点的序列nums=[1 5 6 4 3 2 1]
    • 理解一下题意:将序列中的数字组合成一个整数,将所有数字的不同组合按照从小到大排序:
      • 1123456 < 1123465 < 1123546 < 1123564 < 1123645 < 1123654 < 1124356 < 1124365 < . . . 1123456<1123465<1123546<1123564<1123645<1123654<1124356<1124365<... 1123456<1123465<1123546<1123564<1123645<1123654<1124356<1124365<...
      • 1123456的下一个排列就是1123465
      • 1123465的下一个排列就是1123546
      • … 依次类推
      • 1564321的下一个排列就是1612345
    • 解题步骤
      • step1: 找到右边起第一个极大值的前一个数值: nums[right]

      • step2: 从最右边开始找 nums[right:] 中第一个比 nums[right] 大的数值 nums[search]

      • step3: 交换 nums[right] 和 nums[search]

      • step4: 反转 nums[right:] 数值

        Leetcode31. 下一个排列_第1张图片

2. 代码

from typing import *
class Solution:
    def swap(self, nums: List[int], i:int, j:int) -> None:
        temp = nums[i]
        nums[i] = nums[j]
        nums[j] = temp
        return
    
    def revised(self, nums: List[int], i:int, j:int) -> None:
        start, end = i, j
        while start<end:
            self.swap(nums, start, end)
            start += 1
            end -= 1
        return
    
    def nextPermutation(self, nums: List[int]) -> None:
        right = len(nums)-2
        while right>=0 and nums[right]>=nums[right+1]: right -= 1
        
        if right>=0:  
            search = len(nums)-1
            while search>right and nums[search]<=nums[right]: search-=1  
            self.swap(nums, search, right)
            self.revised(nums, right+1, len(nums)-1)
        else:
            self.revised(nums, 0, len(nums)-1)
        return

你可能感兴趣的:(Leetcode,算法,数据结构,leetcode)