java求全排列
作者:暴力美學求解王
原文:https://blog.csdn.net/a754112602/article/details/81109663
這是我發現java求全排列最好的程式碼,轉過來,分享下
public static void permutation(char[]ss,int i){ if(ss==null||i<0 ||i>ss.length){//1 return; } if(i==ss.length-1){//2 System.out.println(new String(ss)); }else{ for(int j=i;j<ss.length;j++){//3 char temp=ss[j];//交換字首,使之產生下一個字首 ss[j]=ss[i]; ss[i]=temp; permutation(ss,i+1);//4 temp=ss[j]; //將字首換回來,繼續做上一個的字首排列.//5 ss[j]=ss[i]; ss[i]=temp; } } } public static void main(String args[]){ permutation(new char[]{'a','b','c','d'},0); }
再談理解:
這裡採用的是遞迴的方法實現,註釋1不用多說,對要進行全排列的資料進行判空校驗。
這裡先看註釋3,從main方法進來之後會先道註釋3這部分的程式碼,此時i=0,j=0,(陣列內元素{'a','b','c','d'})
可以看到先是a和a交換了位置(相當於沒交換,但也算一種情況),然後進行遞迴呼叫,
從註釋4可以看到i+1,可以想到遞迴呼叫裡面就會依據當前已經交換了的狀態(此處a與a交換)繼續進行交換,
當然下一步遞迴呼叫交換b與b(i變成i+1了嘛),依次類推,但遞迴交換到最後會到註釋2的判斷,
發現此時i已經是陣列的最後一個元素下標了(即已經沒有後續元素給他交換),因此這樣就已經形成了一種排列,輸出排列。
好,第一次輸出結果輸出完了之後,終於有機會到達依次註釋5了,從上面結果分析,
第一次全排列輸出應該是a,b,c,d因為每一次都是和自己的位置做交換,
下面從第一個跳出遞迴的地方分析,
第一次跳出來的是c,此時i=2,j=2
(因為(i+1=陣列長度-1)之後就符合註釋2的判斷,形成一種排列,上面說過,最後一個元素已經沒有後續元素和他進行交換),
跳出遞迴後,就在註釋5處把交換過的字首換回來(雖然這裡無影響)
然後j++之後,然後繼續for迴圈,此時i=2,j=3,
此時終於交換了不同的元素了!交換的是c與d,然後也是遞迴呼叫,但是發現遞迴下去
也是達到了i+1=陣列長度-1 符合註釋2的判斷,所以此時輸出a,b,d,c的排列,好,這裡輸出完之後,也相應地結束了關於c這一次的遞迴呼叫了, 就退到了b(即i=1,j=1)其實到了這裡就和上面的一樣,繼續執行迴圈體,i=1,j=2,然後交換字首,
即b與c交換,然後繼續遞迴呼叫,其實就是在這樣的字首下進行剛剛講過的遞迴過程,
當然注意退出遞迴時,要把之前的交換過的字首換回來,以便下一次字首交換。