Java 寻找给定字符串排列的优化算法?

Java 寻找给定字符串排列的优化算法?,java,algorithm,optimization,permutation,Java,Algorithm,Optimization,Permutation,在下面的代码中,我将查找给定输入字符串的所有可能排列,并将它们存储在一个列表中,然后计算其中的回文数。当输入字符串长度小于10时,这种方法工作正常。但当输入字符串长度大于10时,查找排列将花费大量时间。我想知道这里可以优化什么以获得恒定的执行时间 private static char[] inputArray; private static List<String> listOfpermutations = new ArrayList<>(); private stat

在下面的代码中,我将查找给定输入字符串的所有可能排列,并将它们存储在一个列表中,然后计算其中的回文数。当输入字符串长度小于10时,这种方法工作正常。但当输入字符串长度大于10时,查找排列将花费大量时间。我想知道这里可以优化什么以获得恒定的执行时间

private static char[] inputArray;
private static List<String> listOfpermutations = new ArrayList<>();
private static int count;

public static void main(String s[]) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String input = reader.readLine();
    inputArray = input.toCharArray();
    permutation(0);
    for (String combination : listOfpermutations) {
        if (combination.equals(new StringBuilder(combination).reverse().toString())) {
            count++;
        }
    }
    System.out.println(count);
}

public static void permutation(int start) 
{
    String temp = "";
    if (start != 0) {
        if (start == inputArray.length) {
            for (int i = 0; i < start; i++) {
                temp = temp + inputArray[i];
            }
            if (!listOfpermutations.contains(temp)) {
                listOfpermutations.add(temp);
            }
        }

    }
    for (int i = start; i < inputArray.length; i++) 
    {
        swap(start, i);
        permutation(start + 1);
        swap(start, i);
    }
}

static void swap(int pos1, int pos2) {
    char temp = inputArray[pos1];
    inputArray[pos1] = inputArray[pos2];
    inputArray[pos2] = temp;
}
私有静态字符[]输入阵列;
私有静态列表listOfpermutations=new ArrayList();
私有静态整数计数;
公共静态void main(字符串s[])引发IOException{
BufferedReader reader=新的BufferedReader(新的InputStreamReader(System.in));
字符串输入=reader.readLine();
inputArray=input.toCharArray();
置换(0);
for(字符串组合:术语列表){
if(composition.equals(新的StringBuilder(composition.reverse().toString())){
计数++;
}
}
系统输出打印项次(计数);
}
公共静态无效置换(int开始)
{
字符串temp=“”;
如果(开始!=0){
if(start==inputArray.length){
对于(int i=0;i
测试输入:

  • aaabbb//工作非常棒
  • CCDDCC//工作正常
  • ccccddcce//这里花的时间太长了

  • 如果您不生成所有的n,您可以在运行时间上获得显著的改进!排列

    因为您正在寻找回文,所以您的输入数据应该包含许多重复的字符。生成置换的方式将生成许多相同的置换。(作为副作用,您将多次计算某些排列)

    相反,在中生成置换

    另外,您可以跳过创建完整列表,但只需在生成下一个排列后立即检查回文

    PPS。事实上,阿披舍克·班萨尔的想法相当不错

    计算字符串中每个字符出现的次数。如果回文是可能的, 那么所有的字符都必须有偶数,也许只有一个除外

    将每个计数除以2,并在除法后按字母顺序创建一个包含该计数的字符串。例如,从“abcccabaa”获得字符串“aabc”(请注意,
    c
    具有奇数计数,并且在新字符串中出现一次)

    从生成的字符串中,按字典顺序生成并计算所有排列。 这就是你的答案。您不需要检查回文,因为您可以通过这种方式生成所有可能的回文。每个这样的排列将代表回文的一半。整个回文将是前半部分,可能后面跟一个单数的字符实例,后面跟一个倒数的前半部分。例如,前几个回文是

    "aabc" + "c" + "cbaa"
    "aacb" + "c" + "bcaa"
    "abac" + "c" + "caba"
    

    如果您不生成所有的n,您可以在运行时间上获得显著的改进!排列

    因为您正在寻找回文,所以您的输入数据应该包含许多重复的字符。生成置换的方式将生成许多相同的置换。(作为副作用,您将多次计算某些排列)

    相反,在中生成置换

    另外,您可以跳过创建完整列表,但只需在生成下一个排列后立即检查回文

    PPS。事实上,阿披舍克·班萨尔的想法相当不错

    计算字符串中每个字符出现的次数。如果回文是可能的, 那么所有的字符都必须有偶数,也许只有一个除外

    将每个计数除以2,并在除法后按字母顺序创建一个包含该计数的字符串。例如,从“abcccabaa”获得字符串“aabc”(请注意,
    c
    具有奇数计数,并且在新字符串中出现一次)

    从生成的字符串中,按字典顺序生成并计算所有排列。 这就是你的答案。您不需要检查回文,因为您可以通过这种方式生成所有可能的回文。每个这样的排列将代表回文的一半。整个回文将是前半部分,可能后面跟一个单数的字符实例,后面跟一个倒数的前半部分。例如,前几个回文是

    "aabc" + "c" + "cbaa"
    "aacb" + "c" + "bcaa"
    "abac" + "c" + "caba"
    

    在我看来,这更像是一个数学问题,而不是一个算法问题

    因为您只对回文字符串的数量感兴趣,所以不需要生成所有可能的排列

    计算字符串中每种类型的字符数。将字符除以二。计算该半字符串的排列数。这就是答案,因为字符串的另一半只是镜像了这一半

    例如,如果字符串是aabbcc,则a的计数为2,b的计数为2,c的计数为2

    我们把它们减半,形成abc,用6种方式排列。这将是回文的排列数


    (您需要检查字符串中的字符数是奇数还是偶数)

    在我看来,这更像是一个数学问题,而不是算法问题

    因为您只对回文字符串的数量感兴趣,所以不需要生成所有可能的排列

    计算字符串中每种类型的字符数。划分字符