[leetcode] 31 Next Permutation

题目:
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 and use only constant 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,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

题目大意:
给出一个list,求出它的下一个排列组合,若已经是最大的排列组合,则下一个为最小的那个

题解:
在离散数学这门课中,学过排列组合的算法,在此处用是正好的。以下简介该算法:

设P是[1,n]的一个全排列。
P=P1P2…Pn=P1P2…Pj-1PjPj+1…Pk-1PkPk+1…Pn , j=max{i |Pi < Pi+1}, k=max{i|Pi>Pj} ,对换Pj,Pk,将Pj+1…Pk-1PjPk+1…Pn翻转, P’= P1P2…Pj-1PkPn…Pk+1PjPk-1…Pj+1即P的下一个排列组合。

举一个例子进行解释:
现有1-4-7-5-3-2
1、首先从右边开始比较,求出相邻左边的数比右边的数小的第一对,即j=1,对应的数为4
2、再从右边开始比较,求出比4大的第一个数,k=3,对应的数为5
3、交换arr[k],arr[j],此时变为1-5-7-4-3-2
4、最后,将j+1到n-1的数逆转,得到1-5-2-3-4-7
5、故下一个排列组合为1-5-2-3-4-7

注:由于此题当给出的列表已为最大组合时,输出为最小的排列组合,故此种情况单独处理。

code:

class Solution(object):
    def nextPermutation(self, nums):
        right=nums[len(nums)-1]
        flag=0
        for i in range(len(nums)-2,-1,-1):
            if nums[i]<nums[i+1]:
                j=i
                num=nums[i]
                flag=1
                break
        #此时的情况为,已达到最大的排列组合,故将列表排序后输出
        if flag==0:
            nums.sort()
            print(nums)
            return
        for i in range(len(nums)-1,-1,-1):
            if nums[i]>num:
                k=i
                break
        temp=nums[j]
        nums[j]=nums[k]
        nums[k]=temp
        for i in range(1,(len(nums)-j-1)//2+1):
            temp=nums[j+i]
            nums[j+i]=nums[len(nums)-i]
            nums[len(nums)-i]=temp
        print(nums)
#以下为测试代码,不需要交
arr=[1,2,3]
Solution().nextPermutation(arr)

猜你喜欢

转载自blog.csdn.net/shu_xi/article/details/80133646