問題描述:
輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。
輸入描述:
輸入一個字符串,長度不超過9(可能有字符重複),字符只包括大小寫字母。
分析:
這個題的主要難點在於每個字符的所有排列,下面用的方法是使用遞歸來實現的,如圖(用ABC來舉例)。
過程:(遞歸這一塊可能描述的不是那麼準確)
當剛進去totalOrder這個方法時,此時 index 值爲 0,此時他指向的是第一個元素A(在for循環中,它可以交換3次,和自己交換(沒有變化),和第二個元素B交換,和第三個元素C交換),道理都是一樣的,所以只詳細講一種。當他和自己交換後,然後遞歸進行下一次調用,此時傳入的 index 值已經加一了,也就是說,現在index所指向的是第二個數(有兩次交換機會,和自己,和後面的數),他和自己交換,此時他有進入了下一次的遞歸調用中,因爲他現在已經是最後一個數了,所以將它現在的字符串(ABC)放到list中。然後進行回退,因爲他和自己已經交換了,那麼他就只有和他後面的那個數進行交換,然後又一次進行遞歸,此時他指向最後一個數,所以將它現在的字符串(ACB)再次放到list中,他就開始一層一層回退回去,然後有一次進行交換,遞歸操作,依次類推下去,就能得到字符串的所有排列了。
代碼:
import java.util.*;
public class Solution {
public ArrayList<String> Permutation(String str) {
List<String> list = new ArrayList<String>();
if(str != null && str.length()>0){
totalOrder(str.toCharArray(),0,list);
Collections.sort(list);
}
return (ArrayList)list;
}
public void totalOrder(char[] chars,int index,List<String> list){
if(index == chars.length-1){
String value = String.valueOf(chars);
if(!list.contains(value)){
list.add(value);
}
}else{
for(int i = index;i<chars.length;i++){
swap(chars,i,index);
totalOrder(chars,index+1,list);
swap(chars,i,index);
}
}
}
public void swap(char[] s,int i,int j){
char tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}