从另一组中有效地删除一组整数

时间:2013-12-31 02:28:23

标签: c++ algorithm stl

我有一个(大)整数集S,我想运行以下伪代码:

set result = {};
while(S isn't empty)
{
  int i = S.getArbitraryElement();
  result.insert(i);
  set T = elementsToDelete(i);
  S = S \ T; // set difference
}

函数elementsToDelete是有效的(在S的初始大小中是次线性的)并且T的大小很小(假设它是常数)。 T可能不再包含S中的整数。

有没有办法实现比O(| S | ^ 2)快的上述?我怀疑我应该能得到O(| S | k),其中k是elementsToDelete的时间复杂度。我当然可以使用std::set_difference以简单的方式实现上述内容,但我的理解是set_difference是O(| S |)。

2 个答案:

答案 0 :(得分:1)

使用std::set S;,您可以:

for (auto k : elementsToDelete(i)) {
    S.erase(k);
}

当然erase的查询是O(log(S.size())),而不是您要求的O(1)。这可以通过std::unordered_set来实现,假设没有太多的碰撞(一般来说这是一个很大的假设,但通常尤其如此)。

尽管有名称,但std::set_difference算法与std::set没有多大关系。它适用于您可以按顺序迭代的任何内容。无论如何,它不适用于容器的就地修改。由于T.size()在这种情况下很小,因此每次删除一批元素时,您确实不想创建新容器。在结果集足够小的另一个例子中,它比重复erase更有效。

答案 1 :(得分:0)

C ++库中的set_difference具有O(|S|)的时间复杂度,因此它不适合您的目的所以我建议您使用S.erase()删除O(logN)中实现的S中的set元素作为BST。因此,您的时间复杂度降低到O(NlogN)