全排列:從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 ...