系列文章目录
前言
本人最近再练习算法,所以会发布自己的解题思路,希望大家多指教
一、题目描述
给定一个只包含大写英文字母的字符串S,要求你给出对S重新排列的所有不相同的排列数。
如:S为ABA,则不同的排列有ABA、AAB、BAA三种。
二、输入描述
输入一个长度不超过10的字符串S,确保都是大写的。
三、输出描述
输出S重新排列的所有不相同的排列数(包含自己本身)。
1、输入
ABA
2、输出
3
结果包含:ABA, AAB, BAA
四、java代码
//存放所有的满足条件的字符串集合
static Set<String> strings = new HashSet<>();
//该字段用来标记是否是字符串重新排列后的第一个字符
static int index = 0;
//存放每个字符串的第一个字符
static List<String> list = new ArrayList<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
long l = System.currentTimeMillis();
int dfs = dfs(line, "", 0);
System.out.println("去重前生成的字符串个数:"+dfs);
System.out.println("去重后生成的字符串个数:"+strings.size());
System.out.println("程序执行时间:" + (System.currentTimeMillis() - l)+"ms");
}
private static int dfs(String line, String prefix, int count) {
//当字符串深度遍历完成,将当前字符串存入set集合,且将首个字符存入list
if(line.length() == 0){
strings.add(prefix);
list.add(prefix.substring(0,1));
return ++count;
}
//如果当前字符为新字符串的首个字符,则判断该字符串是否已经作为首字母进行排列组合,避免重复排序
if(index ==1 && list.contains(prefix)){
return count;
}
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
String remaining = line.substring(0,i) + line.substring(i+1);
index++;
//当前是第一次调用该方法 或者 i==0 或者 当前字符和上一个字符不相同,才可进行递归调用
if(prefix == "" || i==0 || (i>0 && c != line.charAt(i-1))){
count = dfs(remaining, prefix+c, count);
}
index--;
}
return count;
}
五、测试用例
输入:
ABCDEFGHHAA
输出: