全排列演算法思想

2022-04-07 08:00:06 字數 2147 閱讀 5516

參考於:【stl】next_permutation的原理和使用

給定乙個數列,如何得到它的全排列?

例如1 2 3

,它的全排列是

123,

132,

213,

231,

312,

321。

全排列的關鍵在於,給定某一數列,能從該數列推出「下乙個」數列。

那麼如何找「下乙個」數列呢?

1、從後往前找兩個相鄰元素,前乙個位置記為i

,後乙個記為

j,並且滿足

s[i] 

2、從後往前找另乙個位置

k,若滿足

s[i] 

,則將s[i]

與s[k]

交換,並將

j之後(包括

j)的所有元素顛倒排序,即得「下乙個」數列。

先試著自己按照這個演算法思路去模擬一下演算法過程,看能不能悟出這個演算法為什麼是對的?如果還是不明白這個演算法為什麼是對的,再繼續往下看。

舉個例子,6 2 5 4 3 1

,觀察一下,下乙個數列是

6 3 1 2 4 5

,回憶一下觀察的過程,你是先從後往前找的對不對?你在找什麼?

其實你在從後往前找,比較相鄰兩個數字,如果前乙個數字比後乙個數字大或相等,就繼續往前找,直到找到前乙個數字比後乙個數字小,我們將前乙個數字的位置記為i

,後乙個數字的位置記為

j,此時應該滿足

s[i]。這個例子中

i = 1

,j = 2

。可以看出從j

開始的數列都是非公升序排列的,因為剛剛在找的過程中,前乙個數字都是比下乙個數字大或相等。

要知道,非公升序排列的數列不可能有「下乙個」數列,即非公升序排列的數列是「最大的」。那麼從j

開始的數列必定不存在「下乙個」數列;另外一點,我們需要考慮i

之前(不包括

i)的數列嗎?比如例子中的

6,不需要!因為從i

開始的數列必定存在「下乙個」數列,因為它不是非公升序排列的,非公升序排列的數列必定存在「下乙個」數列。所以結論是,我們只考慮從從i

開始的數列找「下乙個」數列。

從j開始的數列不可能有「下乙個」數列,那麼「下乙個」數列的i位置放的值不能是原數,而應該從後面的數找,找比原數大的,然後這個數要盡量小。那麼如何找到這個最小的數呢?因為從j

開始的數列是非公升序,所以從後往前找,找到比原數大的就行了。這個位置,我們記為k

,例子中這個最小的數是3,即

k=4。

找到k之後,交換

i,k位置的值(一定可以找到這樣的

k,因為

j位置就滿足了)。交換之後,從j

開始的數列依然是非公升序排列。這個很明顯,就不多解釋了。

因為從j

開始的數列是非公升序排列,逆序一下,得到非降序排列,非降序排列是「最小的」。所以交換之後,從j

開始,逆序排序一下,即得到「下乙個」排列。

下面自己實現的源**(原理同stl中的next_permutation)

bool nextpermutation(int s, int first, int last)    //

last最後乙個元素的下乙個位置

if (i == first) //

找到第乙個元素都找不到,說明該陣列是降序排列的,下乙個排列不存在

i--, j--;}}

view code

ps.理解源**之後就可以知道為什麼降序排列的陣列,用stl中的next_permutation之後變成公升序排列

最後再補充乙個不規範的遞迴版本,所謂不規範,就是排列的順序與stl中的next_permutation不一樣。

void nextpermutationrecursive(int s, int n, int first, int last)    //

last是最後乙個元素的下乙個位置

else

}

}

view code

全排列的演算法思想

前幾天的一道面試題目,要求輸入4個數進行全排列並進行按行輸出,精髓在於運用遞迴的思想。1,2兩個數的全排列是 1,2,3三個數的全排列是 根據以上規律可以看出,假如有n個數則它的全排列是以n個數開頭的 n 1 的全排列,以此類推以下個人的 片段 include include using names...

全排列演算法的遞迴思想及實現

題意 給定1 n n個正整數,寫出它們的所有排列順序。思路 根據高中的知識,我們知道不重複的條件下結果是n 個排列順序,在程式中我們先看看如何用遞迴來實現。例如陣列 1,2,3 的全排列為123,132,213,231.312.321。可以看出一點規律來,我們依次交換了第乙個數字,分別從1到3,後面...

演算法 全排列

從n個不同元素中任取m m n 個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的乙個排列。當m n時所有的排列情況叫全排列。用演算法分別實現全排列,其中n個元素儲存在乙個長度為n的陣列中。實現全排列之前,先看一下對進行全排列的一種方法 從圖中可以看出,我們首先從n個元素中取出乙個元...