全排列的遞迴與非遞迴實現

2022-08-05 01:03:12 字數 1212 閱讀 9607

問題:輸入乙個序列(元素無重複),輸出其全排列

一般採用經典的遞迴解法,後來想將其改造為非遞迴**,思考很久後覺得並不好寫,手工模擬遞迴棧的行為容易出錯。然後上網搜尋了一下眾網友的非遞迴**,發現很多人的非遞迴**是各種全新的求解演算法,而不是相同演算法的非遞迴實現,和我想要的不一樣。

遞迴解法:

假設輸入序列[0,1,2,3],將其分解為4個子問題

0+[1,2,3],

1+[0,2,3],

2+[0,1,3],

3+[0,1,2],這樣每個子問題的規模減小了1,一直遞迴下去直到無法再分解。

1

//對a[idx]~a[n-1]的元素進行全排列,原地排列2//

第乙個引數為序列集合,第二個為序列長度,第三個為當前子問題(子串行)的起始位置

3void recursivepermutation(int a,int n,int

idx)

411 printf("\n"

);12

return;13

}14 assert(idx < n-1

);15

for(int i=idx; i < n; ++i)

1621 }

非遞迴: 

需要乙個資料結構來模擬呼叫棧,std::vector是乙個不錯的選擇,其長度相當於遞迴深度,每個元素用來儲存每次遞迴呼叫中的迴圈變數i。

**流程來說,最外層需要乙個無腦的迴圈,裡面需要

1、判斷某個排列是否結束,並輸出排列值

1

void permutation(int a,int n) //

假設無重複

212 printf("\n"

);13 idx.back()++; //

idx+1,與下面的if配合,回退到上乙個迭代14}

1516

if(idx.back() < n) //

模擬遞迴演算法中的迴圈判斷條件

1722

else

2326

int i =idx.size()-1;27

std::swap( a[i],a[idx.back()]);

28 idx.back()++; //

模擬遞迴演算法中迴圈i的遞增29}

30};

3132 }

全排列 遞迴與非遞迴實現

全排列問題在公司筆試的時候非經常見,這裡介紹其遞迴與非遞迴實現。簡單地說 就是第乙個數分別以後面的數進行交換 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....

全排列的遞迴與非遞迴實現

1 全排列 將n個不同元素按照不同的順序進行排列,一般要求所有的排列方式,或者滿足某些要求的排列方式,比如先後順序的限制 2 遞迴實現全排列 eg 對 a b c d 進行全排列,可以按照以下的步驟 1.a後面加上 b c d 的全排列 2.b後面加上 a c d 的全排列 3.c後面加上 b a ...

全排列遞迴與非遞迴python實現

全排列就是,給定乙個序列,列舉出該序列中元素所有的排列情況,列舉方法有遞迴和非遞迴兩種,詳細可以見這位大神寫的部落格 我只列出來兩個重要的圖吧。1.非遞迴 字典序法 如下圖 1,2,3 的例子 2.遞迴方法 遞迴方法就是將序列中第一位固定,然後將後面n 1為的全排列列舉出來,取遍第一位所有取值,遞迴...