zoukankan      html  css  js  c++  java
  • LeetCode#31 Next Permutation

    Problem Definition:

    Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

    If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

    The replacement must be in-place, do not allocate extra memory.

    Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

    1,2,31,3,2
    3,2,11,2,3
    1,1,51,5,1

    Solution:

    明确一个问题:什么样的组合是最大的?什么样又是最小的?答:非升序的组合最大,非降序的组合最小。

    栗如:3 2 1 是这仨数能组成的组大permutation,栗如:1 2 2 5 是这四个数能组成的最小permutation。

    于是问题变得很straightforward。求下一个permutation,要做的就是以下的事情:

    1)从尾部开始往回,找到第一个发现降序的位置。比如6 7 5 4 3 2 1,找到的位置是6所在的位置,记为 i=0。

    在这个位置之后的 7 5....是降序的,说明已经达到了这些数能组成的最大可能。因此 i 这个位置是第一个如果改变它就能增大整个串的位置。

    当然,比 i 小的某些位置,改变它们也可能增大串,但是因为 i 是最靠后的,因此增大的最小,我们的目标就是最小限度(就是增加到下一个)地增大串。

    如果直到数组首,都没找到这样的位置,说明已经是最大permutation,记 i=-1,并且跳过步骤 2).  O(n)

    2)然后要找一个元素来替换 i 所指的元素。应该从 i 之后的元素里找。已经知道 i 之后的元素是从尾部开始向前呈现升序(或者非降序)的,因此应该从尾部开始往前,

    找到第一个大于 i 所值元素的元素,其位置记为 j。现在交换 i 和 j 指的元素。O(n)

    3)现在的 i 位置的元素,以及比 i 更小的位置的元素,都到了它们应该到的位置。而 i 之后的元素,呈现的是降序(i+1到j-1的元素都大于j的元素,j+1到最尾的元素都小于j的元素)。

    为了使 i+1 开始,到最尾的元素形成它们能形成的最小部分permutation,应该把它们逆置,可以首末两两交换。(如果步骤1)中得到的 i 是 -1,则刚好对应应该把整个串反转的情况)。还是O(n)

    写成代码就是酱紫的:

     1     # @param {integer[]} nums
     2     # @return {void} Do not return anything, modify nums in-place instead.
     3     def nextPermutation(self, nums):
     4         n=len(nums)
     5         if n<2:
     6             return
     7         i,j,pLeft,pRight=n-2,n-1,-1,n-1
     8         while i>=0 and nums[i]>=nums[i+1]:
     9             i-=1
    10         if i>=0:
    11             while j>i and nums[j]<=nums[i]:
    12                 j-=1
    13             #must be j>i
    14             nums[i],nums[j]=nums[j],nums[i]
    15         pLeft=i+1
    16         while pLeft<pRight:
    17             nums[pLeft],nums[pRight]=nums[pRight],nums[pLeft]
    18             pLeft+=1
    19             pRight-=1
  • 相关阅读:
    11G-使用跨平台增量备份减少可移动表空间的停机时间 XTTS (Doc ID 1389592.1)
    如何在asm上定位数据块
    log file switch (checkpoint incomplete)
    踩坑记录(git)-误提交target文件夹删除办法
    踩坑记录(java)-双层增强for调用remove(obj)报错 java.util.ConcurrentModificationException(并发修改异常)
    Zookeeper服务端的创建及简单的客户端创建节点
    SpringAOP(注解方式实现面向切面编程)之常用Before、After、Around
    EasyExcel示例(阿里巴巴)基于Maven
    Redis简单命令(部分示例代码)
    sqlserver日志处理不当而造成的隐患
  • 原文地址:https://www.cnblogs.com/acetseng/p/4694690.html
Copyright © 2011-2022 走看看