1. 程式人生 > >python 全排列 遞迴中的兩種實現

python 全排列 遞迴中的兩種實現

我所知道的全排列有四種:

1.迭代的排列組合全排列(非遞迴):字典序的大小,即傳說中的A33

2.鄰位置對換的全排列(非遞迴):

方法一:生成下一個排列,該方法對重複元素同樣有效

如果可以根據一個排列生成他的下一個排列,那麼生成所有排列也就不在話下了,下面以排列625431為例來說明怎麼生成下一個排列,首先從右向左找到第一個降序對,這裡是25,然後將前面的數字與其後面的大於它的最小數字相替換,這裡是指將2與2後面的大於2的最小數字相替換,被替換數字是3,替換後的序列是635421,此時3後面的數字肯定是一個降序(從左到右)序列,將這個序列顛倒即可,得到631245,這就是625431的下一個序列,初始時應將元素排序,然後逐個生成;

方法二:生成第n個排列

m個元素的排列總數為m!; 假設m個元素初始時已經升序放入集合key中,則第n個排列的第一個元素必然是集合key中第n/(m-1)! 小元素,記為kx, 設定最小元素為第0小元素;接下來在集合key-{kx}中找出第n%(m-1)!個排列;以此類推,迭代找出所求排列的所有元素;

如果有重複元素,則m個元素的排列總數為m1! /(c1! * c2! *….cn!),ci為元素ki的重複次數;集合key也是一個多重集,對重複元素每次也只刪除一個;

3.交換位置的遞迴全排列:程式碼展示

#all permutation


def printInfo():
    print("test info")


def swap(array, end, start):
    temp = array[end]
    array[end] = array[start]
    array[start] = temp

def isSwap(array, end, start):
    for i in range(start, end):
        if(array[i] == array[end]):
            return False
    return True

def all_Permutation(array, n):
    if n == len(array):
        print(array)
        return
    for i in range(n, len(array)):
        if not isSwap(array,i, n):
            return
        swap(array,i,n)
        all_Permutation(array, n+1)
        swap(array, i, n)

if __name__ == '__main__':
    array = ['a','c','c']
    all_Permutation(array, 0)


4.索引陣列選擇的全排列:程式碼展示