全排列演算法,大致來講有四種字典序法,遞增進製數法,遞減進製數法,鄰位對換法,這裡講一下字典序方法。
首先看什麼叫字典序,顧名思義就是按照字典的順序(a-z, 1-9)。以字典序為基礎,我們可以得出任意兩個數字串的大小。
比如字串「abcdg」和「abcfdg」,我們從左到右比較每乙個字元的大小,發現第四個字元『d』和『f』,『f』的字典序更大,因此前乙個字串比後乙個字串的字典序要小。
因此,對與「abc」,他的字典序最大的值是「cba」,最小的值是「abc」,其他的排序的字典序都在他們之間。因此,求乙個串的全排列,我們只需要從串的字典序最小的排列開始,求出當前字典序的下乙個字典序排序,直到字典序的值最大。我們就求出了所有的全排列!!!
對於,「abc」,我們從最小字典序「abc」開始,依次有:
abc(最小) acb bac bca cab cba(最大)
那麼對於當前的序列我們如何求,他的下乙個字典序呢.(
所謂乙個的
下乙個就是這乙個與下乙個之間
沒有其他的)?
一般演算法可以分為三步:
對於串 5,8,7,9,3,6,4,2,1
1.我們從右向左找到第乙個a[i],滿足a【i】
2.我們從a【i】開始向後,找最後乙個a【j】>=a【i】,這裡a【j】=4;
3.交換a【i】,和a【j】,有串 5,8,7,9,4,6,3,2,1
反轉i位置後所有的元素5,8,7,9,
4,1,2,3,6,得到下乙個全排列
//arr是要排列的陣列,n是陣列的長度,當不存在下乙個排列時返回false;
bool nextpermutation(int * arr,int n)
{ int i,j,k;
for(i=n-1;i>0;i--)//從尾巴開始找第乙個arr【i】>arr【i-1】
if(arr[i]>arr[i-1])
break;
if(i==0) //如果沒找到,則輸入的已經是最大字典序
return false;
i--;
for(j=i+1;j=arr[j])//注意這裡是不大於!!!
break;
j--;
swap(arr[i],arr[j]);
j=n-1;i=i+1;
while(i
字典序的不但能解決排列問題,也能解決組合問題,比如:從5個球中取三個,我們只要對0,0,0,1,1這樣乙個陣列按照字典序進行全排列,就能遍歷出所有組合。!!!!!當然,我們可以用stl裡的
next_permutation函式
實現全排列!!!
輸出乙個陣列的全排列
命題 將乙個陣列的全排列輸出,資料無素不重複 暫不考慮重複的情況.如 定乙個這樣乙個數 int a new a 4 輸出結果 1234 1243 1324 1342 1423 1432 2134 2143 2314 2341 2413 2431 3124 3142 3214 3241 3412 34...
找到乙個數的所有字典序即字串的全排列
字典序 對於數字1 2 3.n 的排列,不同排列的先後關係是從左到右逐個比較對應的數字的先後來決定的。例如對於 5個數字的排列 12354 和12345 排列12345 在前,排列 12354 在後。按照這樣的規定,5個數字的所有的排列中最前面的是 12345 最後面的是 54321 字典排序演算法...
字典序下的下乙個排列
一直寫過陣列全排列的演算法,當時接觸的是使用回溯的方法,這樣可以保證生成的全排列一定是按照字典序的,但是今天在做leetcode上的一道題時,問題是要你找到某個排列情況的下乙個按照字典序排列的狀態。如果直接一點,大可從頭開始做全排列,然後到目標狀態時,在做一次即可找到要的狀態,但是如果題目給的狀態非...