/*
* 输入一个字符串,按字典序打印出该字符串中字符的所有排列。
* 例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
* 思路:
* 分治法:将第一个位置的元素与其他所有位置进行交换,
* 之后针对得到的每一个字符串,将第二个位置的元素与其他所有位置进行交换
* ....
*/
import java.util.*;
public class Permutation {
public ArrayList<String> permutation(String str) {
ArrayList<String> list = new ArrayList<String>();
if(str == null || str.length() == 0) return list;
list.add(str);
getList(0, str, list);
Collections.sort(list); //按字母顺序进行排序
return list;
}
public static void getList(int start, String str, ArrayList<String> list) {
if(start >= str.length() - 1) return;
String strBackup = str; //备份str,以备还原现场用
StringBuffer sb = new StringBuffer(strBackup); //可变
for(int i = start;i < str.length() - 1;i ++) {
for(int j = i + 1;j < str.length();j ++) {
char c = sb.charAt(i);
sb.setCharAt(i, sb.charAt(j));
sb.setCharAt(j, c);
//去重
if(!list.contains(sb.toString())) {
list.add(sb.toString());
}
getList(start + 1, sb.toString(), list);
sb = new StringBuffer(strBackup); //还原现场
}
}
return;
}
//非递归方法:这个方法比原来的方法逻辑清晰
ArrayList<String> strList = new ArrayList<String>();
public ArrayList<String> permutation2(String str) {
if(str.length() == 0)
return strList;
strList.add(str);
for(int index = 0;index < str.length() - 1;index ++) { //总共循环的次数
int size = strList.size();
for(int i = 0;i < size;i ++) { //注:这个地方不能写成i < strList.size(),因为一次循环过后strList的size变大了
String strTemp = strList.get(i);
addStr(strTemp, index);
}
}
Collections.sort(strList);
return strList;
}
//将下标不为index的字符和下标是index的字符交换
public void addStr(String str, int index) {
for(int i = index + 1;i < str.length();i ++) {
StringBuffer sb = new StringBuffer(str);
char c = sb.charAt(index);
sb.setCharAt(index, sb.charAt(i));
sb.setCharAt(i, c);
if(!strList.contains(sb.toString())) {
strList.add(sb.toString());
}
}
}
public static void main(String[] args) {
ArrayList<String> list = new Permutation().permutation2("abc");
for(String strTemp : list) {
System.out.print(strTemp + " ");
}
}
}