计算线性时间的交集?

时间:2011-01-09 22:11:36

标签: algorithm math data-structures big-o set-intersection

是否存在一个算法,给定两组,在线性时间内计算它们的交点?

我可以运行两个for循环来检查所有元素对,记录我在两个集合中找到的元素。但是,运行时间为O(n 2 )。我如何在O(n)时间内完成这项工作?

6 个答案:

答案 0 :(得分:34)

这取决于你的设定实施。

如果你有一个哈希集(O(1)查找),那么所有其他海报指示的方法是正确的。迭代第一组中的所有元素。如果它在第二组中,则将其添加到结果中。这在O(n)时间内运行。

如果你有一个树集(O(lg n)查找),那么这种方法将起作用,但它在O(n lg n)时间内运行。你可以做得更好;有一个O(n)解决方案。我假设你有某种迭代器可以按升序遍历两个集合的元素。如果你这样做,那么问题是“按排序顺序给出两个列表,找到它们的交集。”这可以使用您用于合并两个范围的算法的修改版本来完成。我们的想法是跟踪两个迭代器。在每个步骤中,比较范围的第一个元素。如果它们相等,则将元素添加到交集处并向前推进两个迭代器。如果第一个小于第二个,则推进第一个迭代器。如果第一个元素更大,则前进第二个迭代器。这在时间O(n)中运行,因为每次迭代消耗至少一个元素,并且总共只有O(n)个元素。

答案 1 :(得分:9)

我想知道没人提到哈希表 无论你的set实现如何(即使'set'在这里意味着一个简单的数组),你可以

  1. 将第一组的内容放入哈希表和
  2. 迭代第二组,检查哈希表是否包含当前元素。
  3. O(n)

答案 2 :(得分:2)

intersection(a, b):
  result = new empty set
  for x in b:
    if a contains x:
      add x to result

  return result

如果contains测试是常量时间(例如在使用哈希表作为实现的集合中),则此算法为O(n)

答案 3 :(得分:2)

组合两个数组并计算此组合数组中每个元素的出现次数,并将它们放在一个新数组中。然后检查此计数数组以查找包含2的条目,这些元素在两个集合的交集中。

答案 4 :(得分:0)

对于集合1中的所有元素:检查该元素是否在集合2中。您可以实现具有分摊O(1)查找时间的集合。

答案 5 :(得分:0)

如果订购了两个列表中的一个,那么我们可以从无序列表

开始
FUNCTION: INTERSECTION ( LIST A, LIST B )
{
   CREATE C AS EMPTY LIST

   FOR EVERY: NUMBER n IN A
   {
        IF BINARY-SEARCH(n) IN B
        {
            ADD n TO C
        }
   }

   RETURN C
}

Time Complexity = O(n O(BINARY-SEARCH)) = O(n log n)

如果列表B是hashed,那么我们BIG-THETA(C n + T(hash))

其中BIG-THETA是渐近平均值,Cconstant 并且T(hash)是散列函数所需的时间