生成全排列的三種方式 對可重集也適用

2021-09-30 16:52:49 字數 414 閱讀 8230

1:遞迴實現,**來自劉汝佳大神的書《演算法競賽入門經典》

/*  n為集合種元素個數,p陣列存放要生成全排列的陣列,a陣列存放每種排列 

cur表示當前需要確定a陣列的第幾個元素

注意對於可重集,我們需要 不重不漏 地列舉遍目標集合種所有元素

**實現( if(!i || p[i]!=p[i-1]) )

即檢查目標集合中第乙個元素和所有"與前乙個元素不同"的元素

還需注意在呼叫函式之前一定要對目標陣列排序

*/ void print_permutation(int n,int *p,int *a,int cur)

int last=-1; //保證每層解答樹不重不漏地列舉所有的未被訪問過的a[i]值

for( i=0;i}}

生成可重集的排列

發現自己菜的連可重集的排列都求不出來。於是今天看懂 來分析一波。首先想能不能用非可重集做。顯然是錯的,因為同一種排列會被計算多次。所以,應該將同一類的數提取出來,統一填充。體現在演算法中,就是先排序,然後找出每一類的數,在個數不超的情況下,隨便填。include include using name...

列舉排列 生成可重集的排列

輸入陣列p,按照字典序輸出所有的p中元素的全排列 由於c c 語言中的函式在接受陣列引數的時候無法得知陣列的元素個數所以需要傳乙個已經填好的位置個數,或者當前需要確定元素位置cur,還需要傳輸原始陣列p,共四個引數 生成的排列有重複的所以需要統計a 0 a cur 1 中p i 出現的次數c1,以及...

生成可重集的排列 (遞迴過程)

解釋一下劉汝佳的 就是這個遞迴只會考慮相同元素的第乙個,所以與前乙個相同的元素應當被忽略,第乙個元素由於沒有前面的元素,所以應當取走。注意這一行 觀察用例 3 1 1 1 有了這行 只會輸出乙個 1 1 1 但沒有這行 就會輸出27 個 1 1 1 3層迴圈,每層3個 3 3 可重集的全排列2 ru...