题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
题解思路:
本题目为全排列,想到递归处理,思路较为简单,但是涉及类型之间的转换较为麻烦。
难点:
- String->char[],得到字符数组,不支持删除某个字符,因此需要用到ArrayList,而字符数组并不能直接转为ArrayList。
- 不能有重复答案。而使用set会导致答案无序。
解决:
- 基本类型数组转ArrayList见另一篇博客char数组转 ArrayList对象 。
- 使用ArrayList无法去重,所以在添加时查看是否存在。
代码(可直接复制运行):
package com.JZOffer;
import java.util.*;
/*
* 题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,
* 则按字典序打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
* */
public class 字符串的排列 {
public static class Solution {
ArrayList<String> ans = new ArrayList<>();
public ArrayList<String> Permutation(String str) {
if(str.equals("")) return ans;
char[] chars = str.toCharArray();
Arrays.sort(chars);
int len = str.length();
List<Character> strlist = new ArrayList<Character>() {{
for (char c : chars) {
add(c);
}
}};
Solve(strlist, new StringBuilder(""));
return ans;
}
public void Solve(List<Character> list, StringBuilder str) {
if (list.isEmpty()) {
//确保不重复
if (!ans.contains(str.toString())) {
ans.add(str.toString());
}
return ;
} else {
//保存原始list,否则remove元素后不可复原
List<Character> listcopy = new ArrayList<>();
String strcopy = str.toString();
int len = list.size();
listcopy.addAll(list);
for (int i = 0; i < len; i++) {
char c = list.get(i);
list.remove(i);
str = new StringBuilder(strcopy);
str.append(c);
Solve(list, str);
//清空
list.clear();
//重置
list.addAll(listcopy);
}
}
}
}
public static void main(String[] args) {
Solution solution = new Solution();
solution.Permutation("aab");
System.out.println(solution.ans);
}
}