next permutation 全排列演算法

2021-09-22 13:36:41 字數 2702 閱讀 9940

stl提供了兩個用來計算排列組合關係的演算法,分別是next_permutation和prev_permutation。首先我們必須了解什麼是「下乙個」排列組合,什麼是「前乙個」排列組合。考慮三個字元所組成的序列。

這個序列有六個可能的排列組合:abc,acb,bac,bca,cab,cba。這些排列組合根據less-than操作符做字典順序(lexicographical)

的排序。也就是說,abc名列第一,因為每乙個元素都小於其後的元素。acb是次乙個排列組合,因為它是固定了a(序列內最小元素)之後所做的新組合。

同樣道理,那些固定b(序列中次小元素)而做的排列組合,在次序上將先於那些固定c而做的排列組合。以bac和bca為例,bac在bca之前,因為次序ac小於序列ca。面對bca,我們可以說其前乙個排列組合是bac,而其後乙個排列組合是cab。序列abc沒有「前乙個」排列組合,cba沒有「後乙個」排列組合。

next_permutation()會取得[first,last)所標示之序列的下乙個排列組合,如果沒有下乙個排列組合,便返回false;否則返回true。這個演算法有兩個版本。版本一使用元素型別所提供的less-than操作符來決定下乙個排列組合,版本二則是以仿函式comp來決定。

演算法思想:

1.首先從最尾端開始往前尋找兩個相鄰元素,令第一元素為*i,第二元素為*ii,且滿足*i

2.找到這樣一組相鄰元素後,再從最尾端開始往前檢驗,找出第乙個大於*i的元素,令為*j,將i,j元素對調(swap)。

3.再將ii之後的所有元素顛倒(reverse)排序。

舉個例項,假設有序列,下圖便是套用上述演演算法則,一步一步獲得「下乙個」排列組合。圖中只框出那符合「一元素為*i,第二元素為*ii,且滿足*i

以下便是版本一的實現細節。版本二相當類似,就不列出來了。

1 template2

bool

next_permutation(bidrectionaliterator first,bidrectionaliterator last)323

if(i == first) /*

進行至最前面了

*/2428}

29 }

簡單應用輸出序列字典序的全排列。

[**實現]

1 #include2 #include3

using

namespace

std;

4int

main()5;

7 sort(ans,ans+4); /*

這個sort可以不用,因為已經排好序*/8

do/*

注意這步,如果是while迴圈,則需要提前輸出*/9

while(next_permutation(ans,ans+4

));14

return0;

15 }

拓展1.能否直接算出集合的第n個排列?

舉例說明:如7個數的集合為,要求出第n=1654個排列。

(1654 / 6!)取整得2,確定第1位為3(從0開始計數),剩下的6個數,求第1654 % 6!=214個序列;

(214 / 5!)取整得1,確定第2位為2,剩下5個數,求第214 % 5!=94個序列;

(94 / 4!)取整得3,確定第3位為6,剩下4個數,求第94 % 4!=22個序列;

(22 / 3!)取整得3,確定第4位為7,剩下3個數,求第22 % 3!=4個序列;

(4 / 2!)得2,確定第5為5,剩下2個數;由於4 % 2!=0,故第6位和第7位為增序<1 4>;

因此所有排列為:3267514。

[**實現]

1 #include2 #include3

using

namespace

std;

4int

main()5;

7 sort(ans,ans+7); /*

同上可以不用sort */8

int n=0; 9

do//

注意這步,如果是while迴圈,則需要提前輸出

1018 n++;

19 }while(next_permutation(ans,ans+7

));20

return0;

21 }

2. 給定一種排列,如何算出這是第幾個排列呢?

和前乙個問題的推導過程相反。例如3267514:

後6位的全排列為6!,3為中第2個元素(從0開始計數),故2*720=1440;

後5位的全排列為5!,2為中第1個元素,故1*5!=120;

後4位的全排列為4!,6為中第3個元素,故3*4!=72;

後3位的全排列為3!,7為中第3個元素,故3*3!=18;

後2位的全排列為2!,5為中第2個元素,故2*2!=4;

最後2位為增序,因此計數0,求和得:1440+120+72+18+4=1654

這個的**實現,可以用乙個陣列a儲存3267514,然後while呼叫next_permutation(),用n計數,每次與陣列a比較,相等則輸出n;

stl演算法 next permutation剖析

在標準庫演算法中,next permutation應用在數列操作上比較廣泛.這個函式可以計算一組資料的全排列.但是怎麼用,原理如何,我做了簡單的剖析.首先檢視stl中相關資訊.函式原型 template boolnext permutation bidirectionaliterator first...

next permutation原理剖析

最近刷leetcode的時候遇見next permutation這道題,感覺挺有意思的乙個題目,遞迴的方法是較簡單並且容易想到的,在網上搜了其餘的解法,就是std next permutation非遞迴解法,但是讓人不是很舒服的就是關於原理的部分,千篇一律的都是摘抄 stl原始碼剖析 也就是這樣的。...

演算法 Next Permutation問題》

此問題描述如下 給定乙個陣列,首先從後向前找出最長的遞減序列的前乙個元素,比如陣列中,從後向前最長遞減序列是,這個序列的前乙個元素就是4,然後再遞減序列中找到最後乙個比這個數 4 大的數字 就是5 然後將5與4交換,得到新的陣列,然後將交換過後的遞減序列進行翻轉,最後得到的結果就是。如果陣列單調遞減...