两个集合之间的交叉点

时间:2015-10-21 17:17:52

标签: performance collections intersection

我被问到这个面试问题。获得两个集合之间交集的最佳和有效方式,一个非常大,另一个很小。 Java Collection基本上是

2 个答案:

答案 0 :(得分:0)

没有其他信息,您可以做的是在执行n x m比较时节省时间,如下所示:

  1. bigsmall成为尺寸nm的集合。
  2. intersection成为交叉集合(暂时为空)。
  3. hashes成为small中所有元素的哈希集合。
  4. 对于object中的每个big,让h为其哈希整数。
  5. 对于hash集合中的每个hashes值,如果hash = h,则将object与散列为{{1}的small元素进行比较}。如果相同,请将hash添加到object
  6. 因此,我们的想法是比较哈希而不是对象,只比较对象的哈希值是否重合。

    请注意,intersection哈希的附加集合是可以接受的,因为这个可能很小的集合的大小。另请注意,该算法计算small哈希值和相对较少的对象比较。

    以下是Smalltalk中的代码

    n + m

    Smalltalk代码非常紧凑,因为发送到set := small asSet. ^big select: [:o | set includes: o] 的消息includes:的工作方式如上面的步骤5所述。它首先比较哈希,然后根据需要比较对象。 set也是在步骤5中表达选择的一种非常紧凑的方式。

    <强>更新

    如果我们枚举两个集合的元素之间的所有比较,我们将不得不考虑select:对对象,这将考虑订单n x m(big-O表示法)的复杂性。另一方面,如果我们将小集合放入散列集合(就像我在Smalltalk示例中所做的那样),每次我们必须检查O(nm)是否包含small对象时发生的内部测试将具有big的复杂性。鉴于O(1)集合的散列为small,此方法的总复杂度为O(m)

答案 1 :(得分:0)

我们分别调用两个集合largesmall

Java Collection是一个Abstract类 - 您实际上无法直接使用它 - 您必须使用Collection的具体子类之一。对于此问题,您可以使用Set s。 Set只包含唯一元素,并且方法为contains(Object o)。默认情况下,它的子类SortedSet按升序创建。

small复制到Set。它现在没有重复的值。将large复制到第二个Set,这样我们就可以使用其contains()方法。创建一个名为intersection的第三个集合,用于保存交叉点结果。

for-each中的

small元素检查large.contains(element_from_small)每次找到匹配项时,intersection.add(element_from_small)

在运行small结束时,您将拥有两个原始集合中所有对象的交集,没有重复项。如果您想订购,请将其复制到SortedSet,然后按升序排列。