[leetcode]Next Permutation @ Python


原題地址:https://oj.leetcode.com/problems/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, 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,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

解題思路:輸出字典序中的下一個排列。比如123生成的全排列是:123,132,213,231,312,321。那么321的next permutation是123。下面這種算法據說是STL中的經典算法。在當前序列中,從尾端往前尋找兩個相鄰升序元素,升序元素對中的前一個標記為partition。然后再從尾端尋找另一個大於partition的元素,並與partition指向的元素交換,然后將partition后的元素(不包括partition指向的元素)逆序排列。比如14532,那么升序對為45,partition指向4,由於partition之后除了5沒有比4大的數,所以45交換為54,即15432,然后將partition之后的元素逆序排列,即432排列為234,則最后輸出的next permutation為15234。確實很巧妙。

代碼:

class Solution:
    # @param num, a list of integer
    # @return a list of integer
    def nextPermutation(self, num):
        if len(num) <= 1: return num
        partition = -1
        for i in range(len(num)-2, -1, -1):
            if num[i] < num[i+1]:
                partition = i
                break
        if partition == -1: 
            num.reverse()
            return num
        else:
            for i in range(len(num)-1, partition, -1):
                if num[i] > num[partition]:
                    num[i],num[partition] = num[partition],num[i]
                    break
        left = partition+1; right = len(num)-1
        while left < right:
            num[left],num[right] = num[right],num[left]
            left+=1; right-=1
        return num

 改進一點:

class Solution:
    # @param num, a list of integer
    # @return a list of integer
    def nextPermutation(self, num):
        if len(num) <= 1: return num
        partition = -1
        for i in range(len(num)-2, -1, -1):
            if num[i] < num[i+1]:
                partition = i
                break
        if partition == -1: 
            num.reverse()
            return num
        else:
            for i in range(len(num)-1, partition, -1):
                if num[i] > num[partition]:
                    num[i],num[partition] = num[partition],num[i]
                    break
        num[partition+1:len(num)]=num[partition+1:len(num)][::-1]
        return num

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM