全排列的概念
全排列是什麼?
全排列的本質
講人話:從一個數組中抽取確定量數量的元素,組成一個新的數組。並根據題中的問題,對新組成的數組進行條件
判斷。是否滿足條件,如果滿足條件,就做出一定的代碼行爲。
僞代碼如下
全排列函數體(){
數組 [] list =現有確定;
if(滿足條件( list )){
執行目標函數;
return ; 這裏必須要加,不加是給自己debug添堵
}
}
滿足條件(數組[] list){
條件判斷函數;
}
以上是對某一單一排列做出的條件判斷,而我們的目標是對一個數組,[] list,做出條件判斷。那麼問題就來了,如果枚舉出所有的情況呢?
生成一個數組的所有排列
您看到這篇文章的時候應該已經做過一些題了,可能會感覺到非常困惑,爲啥咱就是看不懂他們寫的代碼?
例如有些大佬,交換一下數組中的元素就形成了排列。有些大佬對元素位置判斷一下就形成了排列。
原理講解
從一個數組中取出N個元素,形成一個新的數組。我們實際是按照N位元素,在N的每一位上,不重複的添加元素,並繼
續向下一位添加。(這裏描述有點問題,自己動腦子想一想,兄弟語文不好)
舉例說明:從[1,2,3]中,抽取兩個2元素,組成全排列。當第一位取1的時候,後面的第二位便無法取1,只能取2或
3
看到這裏,你肯定已經明白了全排列用代碼實現的原理(每一位,在當前位可取的範圍進行枚舉,然後轉移到下一位)
如果當前位枚舉了一個元素,則後面位不可使用。
僞代碼:
[] 當前可選取的情況;
for(int i :當前可選取的情況){
當前位置 =i;0
//因爲當前位置選取了i,所以要把i從當前可選取的情況中去除掉,以免後面的元素選取
當前可選取的情況 扣除i;
進行下一層的枚舉(K+1); //確定了第K位,我們現在需要枚舉第K+1位
//當前 層 的所有子情況已經討論完畢,既 ABC ----的情況已經討論完畢,排列將進入ABD----的情況
//i不會在這一層被選取了,所以要恢復i
當前可選取的情況增加i;
}
另一種方式
從當前層開始for循環,交換數組元素。 原理是利用這樣子交換當前層通樣不會重複,自己去想。
這個其實和上面的方法大同小異,只是代碼寫起來少個兩三排。因爲這個方法沒有保證全排列的有序性(出現順序),
自己想一下[1,2,3]的全排列使用這個方法是什麼樣子的。
模板
遞歸出口什麼的多自己想想,懶得寫了,網課殺我
import java.util.*;
public class 藍橋排列 {
static char[] list = "LANQIAO".toCharArray();
static boolean[] vis = new boolean[7];//判斷在當前狀況下,哪一位已經被取了
static char[] put = new char[7]; //存放每一位的情況
public static HashSet<String> set = new HashSet<String>();//用於最終的條件判斷
public static void main(String[] args) {
dfs(0);
for(String i:set) {System.out.println(i);}
System.out.println(set.size());
}
//不知道dfs是什麼的朋友自己百度,這個簡單
public static void dfs(int pos) {
if(pos==7) {//已經枚舉了所有位(7位),進行條件判斷。並中止
set.add(new String(put));
return ;
}
for(int i=0;i<vis.length;i++) {
if(!vis[i]) {
vis[i]=true;
put[pos]=list[i];
dfs(pos+1);
vis[i]=false;
}
}
}
}