問題:輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。
輸入描述:輸入一個字符串,長度不超過9(可能有字符重復),字符只包括大小寫字母。
解決思路:第一遍將第一個字母固定,遍歷所有字母,與第一個字母交換位置,然后固定下一個字母,與其后的所有字母依次交換位置,直到固定最后一個字母。
字符串的全排列是一個概率問題,排除相同字母造成的影響,比如abc的全排列個數為A33 = 6個;
再比如字符串“YONYOU”,先拍出現一次的字母,再排出現兩次的字母,一共是A62C42C22,解釋如下:有6個位置;先排N ,U有6*5=30種;再排Y,Y只有4個坑了有4*3/2=6種;最后2個位置給O,O,所以總共30*6=180種。
算法采用遞歸算法:
1 import java.util.ArrayList; 2 import java.util.Collections; 3 4 /** 5 * 輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。 6 * @author 王任義 7 * 8 */ 9 public class FullPermutation { 10 public static void main(String[] args) { 11 FullPermutation test = new FullPermutation(); 12 System.out.println(test.Permutation("alibaba")); 13 System.out.println(test.count); 14 } 15 public ArrayList<String> Permutation(String str) { 16 ArrayList<String> list = new ArrayList<String>(); 17 PermutationStr(str.toCharArray(),0,list); 18 Collections.sort(list); 19 return list; 20 } 21 public int count = 0; 22 public void PermutationStr(char[] str,int times,ArrayList<String> list){ 23 if(times == str.length-1){ 24 String val = String.valueOf(str); 25 if(!list.contains(val)){ 26 // ++count; 27 // System.out.println(str); 28 list.add(val); 29 } 30 31 }else{ 32 for(int i = times;i<str.length;i++){ 33 swap(str,times,i); 34 PermutationStr(str,times+1,list); 35 swap(str,times,i); 36 } 37 } 38 } 39 private void swap(char[] array,int one,int two){ 40 char tmp = array[one]; 41 array[one] = array[two]; 42 array[two] = tmp; 43 } 44 }
雖然在開始的時候,遞歸在內存使用的是同一個char數組str,但是每次將遞歸完成的結果放到list當中的時候,並不是同一個對象,查看源碼可以發現,String.valueOf(char[])方法最終是新建了一個數組對象,將參數中的值復制到String對象內置的value數組中。