剑指offer第27题:
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
理解:
首先将字符串转换为字符数组进行处理,交换的形式如上图所示,进行递归处理,首先和自己进行交换,然后和第二个、第三个……,后面的进行递归交换,保证所有都交换一遍。交换完毕的标志是index到了字符数组的最后一个,完成一个后就转为字符串存放到TreeSet集合当中,使用Set集合的好处是Set集合的内容是不重复的,这符合了题干的要求,如果使用ArrayList的话会有重复的输出。
import java.util.ArrayList;
import java.util.TreeSet;
public class Solution {
public ArrayList<String> Permutation(String str) {
//建立输出的动态数组
ArrayList<String> result = new ArrayList<>();
if(str == null || str.length()==0){
return result;
}
//转为字符数组
char[] chars = str.toCharArray();
//建立Set集合存放生成的不重复字符串
TreeSet<String> set = new TreeSet<>();
Permutation(chars, 0, set);
//因为是Set,需要用addAll
result.addAll(set);
return result;
}
public void Permutation(char[] chars, int index, TreeSet<String> set){
if(chars==null || chars.length==0){
return;
}
if(index<0 || index>chars.length-1){
return;
}
//满足索引到最后一个的条件,生成一个字符串,存入
if(index == chars.length-1){
set.add(String.valueOf(chars));
}
//循环进行交换
for(int i = index; i < chars.length; i++){
swap(index, i, chars);
Permutation(chars, index+1, set);
//完成了一种情况后要回退一步再进行后面其他情况交换,这步很关键
swap(index, i, chars);
}
}
//交换方法,自写
public void swap(int memberA, int memberB, char[] chars){
char tmp = chars[memberA];
chars[memberA] = chars[memberB];
chars[memberB] = tmp;
}
}
知识点:
- 字符串转为字符数组:str.toCharArray();
- TreeSet set = new TreeSet<>();
- result.addAll(set);
- 字符数组转为字符串:String.valueOf(chars);
- set.add(xx);
- list.add(xx)