從n個不同元素中任取m(m≤n)個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的乙個排列。當m=n時所有的排列情況叫全排列。
公式:全排列數f(n)=n!(定義0!=1)
舉個例子,比如你要對a,b,c三個字元進行全排列,那麼它的全排列有abc,acb,bac,bca,cba,cab這六種可能就是當指標指向第乙個元素a時,它可以是其本身a(即和自己進行交換),還可以和b,c進行交換,故有3種可能,當第乙個元素a確定以後,指標移向第二位置,第二個位置可以和其本身b及其後的元素c進行交換,又可以形成兩種排列,當指標指向第三個元素c的時候,這個時候其後沒有元素了,此時,則確定了一組排列,輸出。但是每次輸出後要把陣列恢復為原來的樣子。
arr[index], arr[position] = arr[position], arr[index] # 還原到交換前的狀態,為了進行下一次交換
arr = [1, 2, 3, 4]
permutations(arr, 0, len(arr))
定義全排列問題:輸入乙個長度為n的列表arr,輸出arr的全排列。
(1)首先可以確定的是,每一種全排列的結果中包含的列表長度均是n。想象面前有n個空盒子,現在要把這n個數放到這些空盒子裡去,每個盒子只能放乙個數。那麼第乙個盒子中可以放的選擇是n種,可以使用乙個迴圈來逐個嘗試。
for index in range(0, len(arr)):
temp[position] = arr[index]
(2)第乙個盒子放完後,就該往第二個盒子裡放了。假設第乙個盒子裡放的是arr的第乙個數,那麼第二個盒子就只能放第2~n個數了(不能重複)。為此引入visit列表用來標記arr中哪些數字被使用過了。初始化:
visit = [true, true, true, true]
這樣,當第乙個位置已經使用過時,就在visit裡做標記:visit = [false, true, true, true]
因此放第乙個盒子的**可以改寫如下:
for index in range(0, len(arr)):
if visit[index] == true:
temp[position] = arr[index]
visit[index] = false
(3)當第k個盒子處理完畢後,處理下乙個盒子直接呼叫dfs(k+1)即可,也就是遞迴呼叫。解決了當下該如何做,下一步也就知道怎麼做了。
(4)遞迴呼叫的一定要注意的問題是遞迴呼叫的出口,否則迴圈呼叫下去程式會崩潰無法執行。在這個問題中什麼時候結束遞迴呼叫呢?答案是當這n個盒子都放滿了,即處理到第n+1個盒子時結束呼叫,同時輸出此時的排列結果。
visit = [true, true, true, true]
temp = ["" for x in range(0, 4)]
def dfs(position):
# 遞迴出口
if position == len(arr):
print(temp)
return
# 遞迴主體
for index in range(0, len(arr)):
if visit[index] == true:
temp[position] = arr[index]
visit[index] = false # 試探
dfs(position + 1)
visit[index] = true # 回溯。非常重要
arr = [1, 2, 3, 4]
dfs(0)
注釋了「非常重要」的語句是不能省略的,省略後僅出現[1, 2, 3, 4]一條結果。dfs(k+1)前後的兩條語句分別稱之為試探和回溯。
permutations方法重在排列:
import itertools
n=3a=[str(i) for i in range(n)]
s=""
s=s.join(a)
for i in itertools.permutations(s,n):
print (''.join(i))
# 結果
012021
102120
201210
combinations方法重在組合:
import itertools
n=3a=[str(i) for i in range(n)]
s=""
s=s.join(a)
for i in itertools.combinations(s,n):
print (''.join(i))
# 結果
012
python回溯演算法全排列 回溯演算法 全排列
1 問題描述 對於給定的集合 a,其中的 n 個元素互不相同,如何輸出這 n 個元素的所有排列 全排列 時間複雜度為o 2n 例如 全排列 2 回溯演算法思想 這裡以 a 為例,來說明全排列的生成方法,對於這個集合,其包含 3 個元素,所有的排列情況有 3 6 種,對於每一種排列,其第乙個元素有 3...
回溯(全排列)
題 輸出自然數 1 到 n 所有不重複的排列,即 n 的全排列,要求所產生的任一數字序列中不允許出現重複的數字。輸入格式 乙個整數 n 1 n 9 輸出格式 由 1 n組成的所有不重複的數字序列,每行乙個序列。每個數字保留 5個常寬。sample input 3sample output 1 2 3...
深度遍歷實現全排列
給定乙個沒有重複數字的序列,返回其所有可能的全排列。示例 輸入 1,2,3 輸出 1,2,3 1,3,2 2,1,3 2,3,1 3,1,2 3,2,1 思路 1 用乙個陣列path來記錄此時生成的結果子集中,每個位置取陣列nums中的哪乙個下標 2 用idx表示在path中確定到哪一位了,當確定到...