python 之遞迴與非遞迴實現全排列

2021-08-20 22:20:10 字數 2983 閱讀 6094

全排列:從n個不同元素中任取m(m≤n)個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的乙個排列。

當m=n時所有的排列情況叫全排列。公式:全排列數f(n)=n!(定義 n 為正整數)

# 給定的元素中,抽取一定數量的元素進行排列,求排列的總數

# 現以26個字母為例,從 a 開始,n 個字母的不同種排列數量為 n! 將這 n! 種不同排列進行輸出  1 <= n <= 26

# eg: n == 3 時,輸出為: bca cba cab acb bac abc

基本思路

1. a    共 1 種情況(1!)

2. ba --> ab  # 將 b 插入到已有元素 a 的前後位置    共 2 種情況(2!)

3. cba cab --> bca bac acb abc  # 將 c 插入到已有元素 ba ab 的前面,中間,後面位置    共 6 種情況(3!)

非遞迴實現

因為需要用到階乘,所以**中定義了階乘函式,並呼叫

def factorial_recursion(n):

if n == 1: return 1

return n * factorial_recursion(n-1)

def permutation_for_loop(n, letter):

# 初始化乙個列表,長度為排列的種數

permutation_list = [0 for i in range(factorial_recursion(n))]

# 建立臨時列表,用於儲存迴圈中元素的排列情況,初始化儲存只有乙個元素是的情況

temporary_list = ['a']

# 從 2 開始迴圈,因為只要乙個元素的情況已儲存

for temp_x in range(2, n+1):

# 計數,根據計數來更新列表 permutation_list 資料

count = 0

# for 迴圈遍歷臨時列表 temporary_list 獲取每乙個元素

for temp_i in temporary_list:

# for 迴圈遍歷從列表 temporary_list 中取得的每乙個元素的子元素

for temp_j in temp_i:

# 字首插入,呼叫 str.replace() 方法返回乙個新的字串,並更新到 permutation_list 相應的位置,同時計數加 1

permutation_list[count] = temp_i.replace(temp_j, letter[temp_x-1] + temp_j)

count += 1

# 完成字尾插入,計數加 1

permutation_list[count] = temp_i + letter[temp_x-1]

count += 1

# 更新臨時列表 permutation_list

temporary_list = permutation_list[:factorial_recursion(temp_x)]

# 返回結果

return permutation_list

遞迴實現,用到了列表的雙層推導

def permutation_recursion(n, letter):

if n == 1: return [letter[n-1]] # 基例

return [i.replace(j, letter[n]+j) for i in permutation_recursion(n-1, letter) for j in i] \

+ [i+letter[n] for i in permutation_recursion(n-1, letter)] # 遞迴鏈條,使用列表的雙層推導實現列表

列表的雙層推導

相當於把雙層 for 迴圈中內層迴圈的表示式放到最前面,兩個 for 迴圈按順序寫

sentence ='i am learning python now!'

lst = [i for x in sentence for i in x]

for i in lst:

print(i, end = '.')

# >>> i. .a.m. .l.e.a.r.n.i.n.g. .p.y.t.h.o.n. .n.o.w.!.

**呼叫測試

letter = 'abcdefghijklmnopqrstuvwxyz'

pfl = permutation_for_loop(4, letter).sort()

for i in range(len(pfl)):

print(pfl[i], end = ' ' if (i+1)%4 != 0 else '\n')

print('###########################################')

pr = permutation_recursion(4, letter).sort()

for i in range(len(pr)):

print(pr[i], end = ' ' if (i+1)%4 != 0 else '\n')

# 執行結果如下:

abcd abdc acbd acdb

adbc adcb bacd badc

bcad bcda bdac bdca

cabd cadb cbad cbda

cdab cdba dabc dacb

dbac dbca dcab dcba

###########################################

abcd abdc acbd acdb

adbc adcb bacd badc

bcad bcda bdac bdca

cabd cadb cbad cbda

cdab cdba dabc dacb

dbac dbca dcab dcba

全排列遞迴與非遞迴python實現

全排列就是,給定乙個序列,列舉出該序列中元素所有的排列情況,列舉方法有遞迴和非遞迴兩種,詳細可以見這位大神寫的部落格 我只列出來兩個重要的圖吧。1.非遞迴 字典序法 如下圖 1,2,3 的例子 2.遞迴方法 遞迴方法就是將序列中第一位固定,然後將後面n 1為的全排列列舉出來,取遍第一位所有取值,遞迴...

全排列 遞迴與非遞迴實現

全排列問題在公司筆試的時候非經常見,這裡介紹其遞迴與非遞迴實現。簡單地說 就是第乙個數分別以後面的數進行交換 e.g e a b c 則 prem e a.perm b,c b.perm a,c c.perm a,b 然後a.perm b,c ab.perm c ac.perm b abc acb....

Python實現二分查詢(遞迴與非遞迴)

二分查詢 每次能夠排除掉一半的資料,查詢的效率非常高,但是侷限性比較大。必須是有序序列才可以使用二分查詢。1.非遞迴演算法 def binary search lis,nun left 0 right len lis 1 while left right 迴圈條件 mid left right 2 ...