全排列的非遞迴實現

2021-09-30 14:37:56 字數 2343 閱讀 9850

以前寫過全排列的遞迴演算法,思路和實現都比較簡單。上週練習python,遇到了全排列的問題,就想著用非遞迴實現實現以下。沒想到從中午想到了半夜,草稿用了好幾張,也沒想到好的idea。第二天早上在地鐵上,在手機撥號頁面演示了一會,竟然有了思路。

假定:從小打大排序,稱為正序,反之稱為逆序

我的思路是:以數字序列 312為例,排序後123,排列有 [123,132,213,231,312,321],第一項和最後一項分別是正序和逆序,每一項的值遞增的。

如果設計一套流程,保證從正序到逆序,按值遞增的原則,生成每一項,就完成了這個序列的全排列

那麼怎麼實現這個遞增過程呢,經過一系列的手算,我發現了一些規律:

判斷是否逆序,如果不是逆序進行下一步,否則,完成排列。

從右往左尋找第乙個數a,使得a小於它右邊相鄰的數b從b到往右到末尾尋找c, 使得c是最小的大於a的數。因為a右邊的序列(不含a)是有序的,所以只需找到比a小的數的左邊的數。如果都大於a,則取最右邊一位

交換a和c

b到末尾按正序排序

舉幾個例子:

例子1:

09442,

1. 一眼看出,不是逆序

2. 從右往左查詢第乙個小於右鄰的數,找到0

3. 然後從9往右找最小的大於0的數為2

4. 0和2交換得:29440

5. 9到末尾正序排序得:20449

從09442到20449,有值位於這兩個數之間的排列嗎?沒有的話,這個就是我們尋找的值。

例子2:

38521

1. 非逆序

2. 找到3<8

3. 找到5>3>2,之前說了,3後面是有序的,2<3,後面就不用找了,最小的大於3的就是5

4. 3和5換位得:58321

8到末尾正序重排得:51238

例子3:

12 1. 非逆序

2. 1

3. 2

4. 1、2交換得21

5. 2到末尾交換得21

python新手,現學現用,下面是python3實現:

def

reverse_at

(sstr, i, j):

return sstr[:i] + sstr[i:j + 1][::-1]

defnext_permu

(sstr):

slen = len(sstr)

tmp = -1

tmp2 = -1

for i in range(0, slen - 1)[::-1]:

if sstr[i] < sstr[i + 1]:

tmp = i

break

if tmp != -1:

for j in range(tmp + 1, len(sstr) - 1):

if sstr[j] > sstr[tmp] and sstr[j + 1] <= sstr[tmp]:

tmp2 = j

if tmp2 == -1:

tmp2 = slen - 1

sstr = swap(sstr, tmp, tmp2)

sstr = reverse_at(sstr, tmp + 1, slen - 1)

return sstr

return

none

defswap

(str, i, j):

str=list(str)

ch = str[i]

str[i] = str[j]

str[j] = ch

return str

defpermutations

(sstr):

print(sstr)

lst=sstr

while

not is_reversed(sstr):

sstr = next_permu(sstr)

lst+= ' ' + ''.join(sstr)

return lst.split()

defis_reversed

(sstr):

for i in range(0, len(sstr) - 1):

if sstr[i] < sstr[i + 1]:

return

false

return

true

print(permutations(''.join(sorted('bcad'))))

非遞迴全排列實現

include include include include include include include includeusing namespace std const int max size 1000 尋找下乙個排列 假設 某個序列為 d1 d2 d3 dn 那麼在dn前找第乙個 比dn...

非遞迴實現全排列

要求 使用非遞迴的方法按照字典序輸出全排列 思路 這次以 1 5 4 3 2 為例,下乙個排列是 2 1 3 4 5 從後往前找,找到第乙個連續遞增的兩個數字,找到了 1 5 重新從後往前找,找到第乙個大於 1 的數字,找到了 2 1 就是步驟三中找到的第乙個數字 找到 2 之後,將 1 和 2 互...

全排列 遞迴與非遞迴實現

全排列問題在公司筆試的時候非經常見,這裡介紹其遞迴與非遞迴實現。簡單地說 就是第乙個數分別以後面的數進行交換 e.g e a b c 則 prem e a.perm b,c b.perm a,c c.perm a,b 然後a.perm b,c ab.perm c ac.perm b abc acb....