Java 修改算法以在包含重复项的字符串中生成唯一排列

Java 修改算法以在包含重复项的字符串中生成唯一排列,java,algorithm,recursion,permutation,dynamic-programming,Java,Algorithm,Recursion,Permutation,Dynamic Programming,如果我使用交换和置换方法来生成置换,我知道如何处理重复的问题,如图所示 但是,我使用了一种不同的方法,在没有当前字符的情况下生成的所有排列的开头和结尾,我将当前字符放置在任意两个字符之间 如何修改下面的代码,以便在包含重复项的字符串中只提供唯一的排列 import java.util.ArrayList; public class Permutations { public static void main(String[] args) { String str = "

如果我使用交换和置换方法来生成置换,我知道如何处理重复的问题,如图所示

但是,我使用了一种不同的方法,在没有当前字符的情况下生成的所有排列的开头和结尾,我将当前字符放置在任意两个字符之间

如何修改下面的代码,以便在包含重复项的字符串中只提供唯一的排列

import java.util.ArrayList;

public class Permutations {
    public static void main(String[] args) {
        String str = "baab";
        System.out.println(fun(str, 0));
        System.out.println("number of Permutations =="+fun(str, 0).size());
    }

    static ArrayList<String> fun(String str, int index)
    {
        if(index == str.length())
        {
            ArrayList<String> al = new ArrayList<String>();
            al.add("");
            return al;
        }

        /* get return from lower frame */
        ArrayList<String> rec = fun(str, index+1);

        /* get character here */
        char c = str.charAt(index);

        /* to each of the returned Strings in ArrayList, add str.charAt(j) */
        ArrayList<String> ret = new ArrayList<String>();
        for(int i = 0;i<rec.size();i++)
        {
            String here = rec.get(i);
            ret.add(c + here);
            for(int j = 0;j<here.length();j++)
                ret.add(here.substring(0,j+1) + c + here.substring(j+1,here.length()));
        }
        return ret;
    }
}

PS:我不想使用hashmap/Set来跟踪我的重复项,并查看它们以前是否遇到过。

当您在字符串中迭代并在每个位置添加字符时,如果您在字符串中找到与插入的字符相同的字符,在紧接新字符之前插入新字符后中断。这意味着具有相同字符多次的字符串只能以一种方式形成(以相反顺序插入),因此不会发生重复

for(int j = 0;j<here.length();j++)
{
    if(here.charAt(j) == c)
        break;  
    ret.add(here.substring(0,j+1) + c + here.substring(j+1,here.length()));
}

用于(int j=0;jIs这不是Codechef提出的问题?@VaibhavBajaj,您好。正如我所说,我知道解决这个问题的解决方案,我正在寻找对这个特定实现的修改。这太优雅了。Abs太棒了!刚才有一个问题。比方说,我们的字符串是babcd。比方说,我已经用abcd生成了所有24个排列,现在,在e步骤,我将在每个位置插入b。根据您的逻辑,对于像abcd这样的字符串,在添加“b”时,我们会生成1)babcd和2)abbcd,但之后会断开。我的问题是,再次忽略像ab+'b'+cd==abbcd这样的排列是有意义的。但是我们怎么能忽略前面的组合,比如abc+b+d==abcbd。我画了递归,看到它们是在其他框架中生成的。但是,所有这些都是如何处理的呢?这将通过生成acbd,然后在第二个位置插入b来处理,这并不违反规则。这意味着只能在字符串中该字符的现有实例之前将该字符添加到字符串中。例如,将b添加到abcd以制作babcd是可以的。将b添加到abcd以生成abcbd是不合适的。另一种方法是:假设您排列字符串abb并获得两个重复的bab。一个是在ab的开头加上b,一个是在ba的末尾加上b。禁用第二个将删除重复项。
for(int j = 0;j<here.length();j++)
{
    if(here.charAt(j) == c)
        break;  
    ret.add(here.substring(0,j+1) + c + here.substring(j+1,here.length()));
}