【问题标题】:Finding pairs of duplicates in a Java ArrayList在 Java ArrayList 中查找重复项对
【发布时间】:2012-03-16 10:33:59
【问题描述】:

我正在寻找 Java ArrayList 中重复 pairs 的数量。

我可以在纸上算出来,但我不知道是否有某种形式的数学公式可以轻松解决这个问题,因为我试图避免在我的代码中嵌套 for 循环。

使用数据集 [2,2,3,2,2] 的示例: 0:1、0:3、0:4、1:3、1:4、3:4。所以答案是六对重复?

【问题讨论】:

  • 数字的顺序重要吗?
  • 不,我想它不是,因为我实际上希望根据有多少碰撞对来执行功能。
  • 您是否应该在重复对中包含3:4
  • 是的,我应该这样做!已编辑,谢谢:)

标签: java algorithm math


【解决方案1】:

您只需要计算每个数字出现的次数(我会在此处使用地图),然后为每个计数 > 1 的数字计算该计数的 2 组合 (http://en.wikipedia.org/wiki/Combination)。

所以基本上你需要一种方法来计算n!/k!(n-k)!,其中k 为2,n 为计数。

以您的示例 [2,2,3,2,2] 为例,数字 2 出现了 4 次,因此数学运算如下:

4!/2!(4-2)! = 24/4 = 6 --> 6 对

如果你不想实现阶乘函数,你可以使用 Apache Commons 的 ArithmeticUtils,他们已经有了factorial implemented

【讨论】:

    【解决方案2】:

    如果您想避免嵌套循环(以有 2 个循环为代价),您可以:

    1. 对于列表中的每个数字,找出每个数字重复了多少次(可以使用键 = 数字、值 = 列表中该数字出现的次数的 Map)
    2. 对于地图中的每个数字,根据它出现的次数计算可能的组合数(0 或 1 次 = 没有重复对,2 次或更多 = n!/(2*(n-2)!) = (n*(n-1))/2 重复对)
    3. 总结所有可能的组合

    像 ElKamina 建议的那样进行排序将允许对此方法进行一些优化。

    【讨论】:

      【解决方案3】:

      首先对数字进行排序。稍后,如果有给定号码的k 副本,则该号码将有k*(k-1)/2 对。现在将所有数字相加。

      【讨论】:

        【解决方案4】:

        使用Guava,如果您的元素是Strings:

        Multiset<String> multiset = HashMultiset.create(list);
        int pairs = 0;
        for(Multiset.Entry<String> entry : multiset.entrySet()) {
          pairs += IntMath.binomial(entry.getCount(), 2);
        }
        return pairs;
        

        这使用 Guava 的 Multisetmath 实用程序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-08-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-12
          • 2011-11-09
          • 1970-01-01
          相关资源
          最近更新 更多