问题:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串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数组中。