全排列(Java語言實現perm)

2021-09-12 17:53:14 字數 1568 閱讀 7409

全排列(perm演算法)是一種典型的列舉方法。

在解決簡單的排列問題(要排列的元素數量較少)時,如果無法利用貪心演算法或者dp求解或者是一時想不出有效的演算法,通過全排列可以解決較多型別的問題,儘管在時間和空間上無法保證總是滿足要求。

舉乙個栗子:

乙個陣列長度為三:;

那麼他的全排列有3!= 6種。即~

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

解決思路:

陣列長度為3,則經歷排序之後的陣列依然是3(廢話),只不過是在下標0 1 2…所在的位置被賦予了新的元素,而陣列的每乙個下標所在的單元可以存放原陣列中的任意值。首先我們對陣列進行遍歷依次把每乙個下標可以放置的元素進行試探最終就可得到結果(這是二叉樹的變形)。

首先考慮0下標:

此時 原陣列中的元素 123都沒有被裝入0下標所在的單元。我們先把0單元裝入,共有三種情況。(沒有賦值的單元用-1代替)。

1 -1 -1

2 -1 -1

3 -1 -1

然後對於下標0儲存數值1的情況,由於1已經儲存,還有2和3沒有儲存,所以下標為1的單元只有兩種選擇即 2 和 3,我們把它們分別寫入 。對於下標0儲存2和3的兩種情況採用類似的方式處理即

1 2 -1

1 3 -1

2 1 -1

2 3 -1

3 1 -1

3 2 -1

此時原陣列只有最後乙個元素沒有安置,同時也只有最後乙個下標沒有被賦值所以沒有其他情況

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

原陣列中有元素3個其全排列為3!= 6個正好滿足。

看一下具體演算法:

public class main

public static void perm(int list,int start,int finish) {

if(start == finish) {

for(int i = 0;i以下是控制台列印

1 2 3

1 3 2

2 1 3

2 3 1

3 2 1

3 1 2

如果是第一次見到這個**可能會不太理解(理解的就算了),在下第一次看到這段**反正是一臉懵逼,原理和二叉樹一樣為什麼**看起來卻差別這麼大。

實際上原理也很簡單:

對於原陣列我們通過for迴圈把陣列的每乙個元素都與下標為i的那個元素交換(包括自身和自身交換)這樣就等同於把所有原陣列所有還沒有確定位置的元素都放在i上進行嘗試。比如第一輪迴圈的時候i的值等於0,然後每一步交換乙個值,把下標為0 1 2 3…的所有元素都放在下標為零上。放完乙個數值之後遞迴呼叫進行下一輪的交換(不是下一步的交換)當已經沒有數值可以交換的時候就代表迴圈已經結束,一種可行的排列方式已經產出於是進行控制台輸出。

全排列也是典型的把大問題簡化為小問題進行逐個擊破的例子。

在編譯原理的理論中,遞迴的演算法都可以通過堆疊實現。通過堆疊實現可以提高效率但不管是遞迴還是堆疊其基本原理還是相同的。

全排列 (C語言實現)

題目 輸入乙個字串,列印出該字串中字元的所有排列。例如輸入字串abc,則輸出由字元a b c 所能排列出來的所有字串 abc acb bac bca cab 和cba。一 遞迴實現 從集合中依次選出每乙個元素,作為排列的第乙個元素,然後對剩餘的元素進行全排列,如此遞迴處理,從而得到所有元素的全排列。...

C語言實現全排列演算法

題目 輸入乙個字串,列印出該字串中字元的所有排列。例如輸入字串abc,則輸出由字元a b c 所能排列出來的所有字串 abc acb bac bca cab 和cba。includeusing namespace std void permutation char pstr,char pbegin ...

C語言實現排列組合(全排列)

題目描述 排列與組合是常用的數學方法。先給乙個正整數 1 n 10 例如n 3,所有組合,並且按字典序輸出 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 輸入 輸入乙個整數n 1 n 10 輸出 輸出所有全排列 每個全排列一行,相鄰兩個數用空格隔開 最後乙個數後面沒有空格 ...