全排列(遞迴框架)

2021-09-12 01:43:43 字數 1553 閱讀 3673

1. 全排列

在很多情況下都是非常有用的,所以掌握全排列的寫法是非常重要的,而全排列又有很多種的寫法,下面是使用遞迴求解的方法來計算出1-10範圍內的全排列

2. 思路分析:

① 首先我們可以宣告乙個陣列,初始化陣列元素為1-10,使用遞迴的思想,將陣列上的當前這一位上的數字與其他位上的數字進行交換,交換兩個位置上的數字那麼就形成了乙個排列,所以在遞迴的方法中我們需要使用乙個變數來記錄當前的位置是第幾個的位置,這樣就可以使用乙個for迴圈將當前位置上的數字與其他位置上的數字進行交換,在for迴圈中進行遞迴呼叫

for(int i = k; i < arr.length; i++)
k這個變數表示的是當前的位置,當一次全排列呼叫完成,退回到當前這一層,進入到迴圈的下一次,嘗試k在與i + 1這個位置上進行交換,假如我們需要對形成的全排列要有順序那麼我們需要在呼叫完一層退回來之後將其恢復到原來的狀態,這也就是回溯,假如我們不需要從小到大進行排列那麼我們就不需要進行回溯,那麼這樣就只是對陣列元素進行了交換

例如,某一次f遞迴函式呼叫完形成的的數字串行為123456798,假如不進行回溯的話那麼下一次遞迴呼叫形成的序列就是123456978,這是因為上一次交換之後的序列123456798沒有恢復到原來的狀態,所以形成的序列就是沒有順序的,假如進行回溯的那麼會恢復到之前交換之前的那個狀態,即123456789,形成的序列就是123456879,形成的序列就是有序的,所以我們可以根據自己的需要看是否要進行回溯

② 實際上當前這一位與當前這一位以後的位置(也包括當前自己的位置)上進行交換的過程其實就是深度優先搜尋的過程,存在著多分支的搜尋,但是為什麼會與交換自己以及以後的位置呢?1與後面的元素進行交換,當到2這個平行狀態的時候,因為之前1已經與2這個位置已經交換完了,所以不需要再進行交換了,其他的元素也是一樣的道理

重點是能夠理解多分支的遞迴,先總後橫的特點,先搜尋出滿足條件的一種可能,然後退回來搜尋其他的可能,所以求解的過程充分體現了遞迴的先縱後橫,一條路走到黑的特點

總結一下:這其中體現了遞迴的特點,先一直嘗試走下去,然後退回來嘗試其他的位置與當前的這個位置進行交換,也就是先縱後橫,先一條路走到黑,再走平行狀態,假如我們需要形成的序列有序,那麼退回到平行狀態需要進行回溯,因為陣列交換之後對於下乙個形成的序列是有影響的,我們必須把陣列恢復到原來的狀態

所以我們在寫全排列的時候直接套用這個模板就可以輕鬆寫出全排列了

3. **如下:

public class main ;

//可以計算出來10的階乘為362880

f(arr, 0);

system.out.println(count);

} private static void f(int arr, int k)

system.out.print("\n");

}return;

} //使用的思路是交換當前位置的數字與其他位置的數字那麼就形成了全排列

for(int i = k; i < arr.length; i++)

}}

46 全排列 全排列 遞迴

遞迴的時候每次確定乙個位置的數字 nums陣列在遞迴過程中分為左右兩部分,左邊部分是已經確定好的部分,而右邊是待確定數字的部分。每次都嘗試用當前位置右邊的數字來交換當前數字以確定當前數字。題目可以使用collections來優化。詳見 class solution 遞迴過程中每次確定乙個位置的數,遞...

遞迴全排列

遞迴思想,用重複的簡單過程實現乙個複雜的專案,遞迴要素有 1 遞迴的每一層,規模要逐漸縮小 2 遞迴必須有出口,一般每個遞迴函式一開始,是判斷遞迴成立的條件 3 遞迴包括遞進過程和返回過程 4 要注意遞迴實現次數,一般在呼叫遞迴函式前加上遞迴重複條件 常見的結構是 遞迴函式 if 條件成立,例如規模...

全排列(遞迴)

給定乙個由不同的小寫字母組成的字串,輸出這個字串的所有全排列。我們假設對於小寫字母有 a b y z 而且給定的字串中的字母已經按照從小到大的順序排列。輸入只有一行,是乙個由不同的小寫字母組成的字串,已知字串的長度在1到6之間。輸出這個字串的所有排列方式,每行乙個排列。要求字母序比較小的排列在前面。...