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