面试题38:字符串的排列
题目描述
输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
问题分析
把字符串分为两部分:一部分是第一个字符,另一部分是后面的所有字符。
首先,我们要确定第一个字符,该字符可以是字符串中的任意一个;其次固定第一个字符后,求出后面所有字符的排列。
实现第一个字符的改变,仅需将第一个字符和后面所有字符进行交换即可。
要记得字符串输出后要将字符变回原始的字符串。只有这样 ABC字符串才能够出现Swap A with A/B/C 的情况,如果Swap A with B之后不变回原始的字符串,我们后面的操作就基于BAC了,Swap A with A/C就不容易实现了。从下图可以看出
完整的交换图示如下:
问题解答
public ArrayList<String> Permutation(String str) {
ArrayList<String> list = new ArrayList<>();
if(str==null || str.length()==0) {
return list;
}
permutationCore(str.toCharArray(),0,list);
Collections.sort(list); //将list中的字符串排序
return list;
}
private void permutationCore(char[] strArray,int index,ArrayList<String> list){
if(index==strArray.length-1){
//判断是否有重复字符串
if(!list.contains(String.valueOf(strArray))) {
list.add(String.valueOf(strArray));
}
} else {
for(int i=index;i<strArray.length;i++){
// 交换
char temp=strArray[index];
strArray[index]=strArray[i];
strArray[i]=temp;
permutationCore(strArray,index+1,list);
// 重置回来
strArray[i]=strArray[index];
strArray[index]=temp;
}
}
}