問題:輸入乙個序列(元素無重複),輸出其全排列
一般採用經典的遞迴解法,後來想將其改造為非遞迴**,思考很久後覺得並不好寫,手工模擬遞迴棧的行為容易出錯。然後上網搜尋了一下眾網友的非遞迴**,發現很多人的非遞迴**是各種全新的求解演算法,而不是相同演算法的非遞迴實現,和我想要的不一樣。
遞迴解法:
假設輸入序列[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、判斷某個排列是否結束,並輸出排列值
1void 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為的全排列列舉出來,取遍第一位所有取值,遞迴...