【问题标题】:modifying algorithm to generate unique permutations in a string that contains duplicates修改算法以在包含重复项的字符串中生成唯一排列
【发布时间】:2016-07-29 22:20:26
【问题描述】:

如果我要使用交换和置换方法来生成排列,我知道如何处理重复问题,如 here 所示。

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

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

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;
    }
}

此时,“bab”等字符串生成如下输出,其中多次包含abb和bba。

[bab, abb, abb, bba, bba, bab]
number of Permutations ==6

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

【问题讨论】:

  • 这不是 Codechef 的问题吗?
  • @VaibhavBajaj,嗨。正如我所说,我知道解决问题的解决方案,我正在寻找针对此特定实现的修改。

标签: java algorithm recursion permutation dynamic-programming


【解决方案1】:

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

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()));
}

解决这些涉及无重复生成集的问题的一般方法是考虑每个重复集只有一个具有的属性,然后将其作为约束强制执行。例如,在这种情况下,约束是“所有重复的字符都以相反的顺序添加”(正向顺序也可以,但您必须翻转循环方向)。对于顺序不重要的组合问题,约束可以是“每个列表中的项目按升序排列”。以此类推。

【讨论】:

  • 这太优雅了。腹肌棒棒哒!
  • 刚刚有一个问题。比如说,我们的字符串是 babcd。比如说,我已经用 abcd 生成了所有 24 个排列,现在,我将在每个位置插入 b 。根据您的逻辑,对于像 abcd 这样的字符串,在添加 'b' 后,我们会生成 1) babcd 和 2) abbcd,但之后会中断。我的问题是,再次忽略像 ab + 'b' + cd == abbcd 这样的排列是有意义的。但是我们怎么能忽略前面的组合,例如 abc + b + d == abcbd。我画了递归,发现这些是在其他框架中生成的。但是这些都是怎么处理的呢?
  • 这将通过生成 acbd 然后在第二个位置插入 b 来处理,这不会违反规则。
  • 这意味着一个字符只能在字符串中该字符的现有实例之前添加到字符串中。例如。将 b 添加到 abcd 以制作 babcd 是可以的。 abcd 加 b 做 abcbd 不行。
  • 另一种看待它的方式:假设您置换字符串 abb 并获得两个 bab 副本。通过将 b 添加到 ab 的开头可以形成一个。通过在 ba 的末尾添加 b 可以形成一个。禁止第二个删除重复项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-17
  • 2017-04-06
  • 2018-07-15
  • 2014-06-09
  • 1970-01-01
相关资源
最近更新 更多