【LeetCode】31. 下一个排列&II

573 阅读2分钟

image.png

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。

怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~

一、题目描述:

  • 题目内容

    image.png

  • 题目示例

    image.png

  • 题目解析

    • 1 <= nums.length <= 100
    • 0 <= nums[i] <= 100

二、思路分析:

我们拿到本题,读取题意要求求出字典排序的列表元素下一个排序位置,题目要求看起来迷糊迷糊。不用担心,我们继续挖掘题目细节点:

  • arr 数组是整数元素组成的,只能原地修改列表元素之间的位置
  • arr 整数数组下一个排列是指其整数的下一个字典序更大的排列的
  • arr[i-1] < arr[i]时,arr[i]排序的顺序的特点是升序排序
  • 当 arr 整数数组不存在下一个更大的排列,则整个数组直接进行升序排序

我们题目中细节进行了解了,接下要对arr数组进行下一个排序思路如下:

  • 定义一个指针left,指向arr数组末尾len(arr)-1位置
  • 从右往左遍历,当arr[left] > arr[left-1] 时,则记录下left值
  • 定义一个指针right并指向len(arr)-1位置,从右往左查找,找到arr[right]>arr[left-1]时,arr[right]与arr[left-1]进行交换
  • 定义一个指针i,j。i指向left,j指向len(arr)-1,arr[left::]里的元素进行reverse翻转

根据思路总结成三个步骤:一确定i与i-1的零界点,二是找到第一个比i-1大的元素并进行交换,三是对i~len(arr)-1进行互换

按照上述思路,把三个步骤分别使用while来实现,如下:

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

        left,right,k= len(nums)-2,len(nums)-1,len(nums)-1

        while left >=0 and nums[left] >= nums[right]:
            left -=1
            right -=1
        
        if left >=0:
            while k >=0 :
                if nums[k] > nums[left]:
                    nums[left],nums[k] = nums[k],nums[left]
                    break
                k -=1
        i,j = right,len(nums)-1
        while i < j :
            nums[i],nums[j] = nums[j],nums[i]
            i +=1
            j -=1

针对以上思路,我们也可以写在一个while内,代码如下:

class Solution(object):
    def nextPermutation(self, nums):
        """
        :type nums: List[int]
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        left = len(nums)-1

        while left>0:
            if nums[left] > nums[left-1]:
                right = len(nums)-1
                while right>=0:
                    if nums[right] > nums[left-1]:
                        nums[left-1],nums[right] = nums[right],nums[left-1]
                        break
                    right -=1
                i,j = left,len(nums)-1
                while i < j:
                    if nums[i] > nums[j]:
                        nums[i],nums[j] = nums[j],nums[i]
                    i +=1
                    j -=1
                return
            else:
                left -=1
        nums.sort()
        return

同理,在LeetCode中,相似题目如下一个排序II,题目标题如下:

image.png

仍然是采取以上思路进行求解,在进行排序前需要将整数参数转换成列表形式即可。

三、总结:

本期考察我们对字典排序下一个排序思路进行模拟,找到arr[i]和arr[i-1]的临界点,并且在arr[i-1]右边的元素是递增关系,AC代码记录如下: image.png

  • 时间复杂度O(n),n为arr长度
  • 空间复杂度O(1),原地修改

以上是本期内容,欢迎大佬们点赞评论,下期见~~