[英]What is the time complexity of std::deque::erase function?
在这里,它说明了时间的复杂性:
线性删除的元素数(破坏)。 另外, 取决于特定的库实现 ,在位置与双端队列的两端之间的元素数量上,最多需要额外的线性时间。
从第一句话我知道,如果要删除双端队列中的任何数字,则最坏情况下的复杂度将为O(1)。
现在第二句话使我感到困惑。 取决于特定的库实现是什么意思? 我正在使用STL库,该库与GCC编译器一起提供。 在我的情况下,如何学习此函数的正确时间复杂度?
我需要将其设置为O(1),因为我正在运行O(n)擦除调用,如果std::deque::erase
为O(n),我的算法将具有二次复杂度,这是我不想要的。
如果必须从双端队列中删除n
项目,通常需要使用remove/erase
习惯用法。
您从std::remove
开始删除n
项本身。 这基本上将您的集合分为两部分:一开始是您没有删除的部分,另一部分是您不再关心的内容。
它返回一个指向这两个边界的迭代器。 然后,您可以从那里擦除到结尾(一次),以摆脱不再关心的项目。
std::remove
基本上执行了我认为的“波纹复制”操作-从头到尾遍历整个集合,当找到要删除的项目时,它会找到要保留的下一个项目,并且将其复制到要删除的文件1 。
如果您不需要维护所保存物品的顺序,则通常可以进一步提高速度。 从集合的开头开始,找到您要删除的项目(即,您当前要erase
)。 从年底开始找到你想要保存项目(即,一个你不会 erase
)。 交换这两个项目,然后继续“向内”搜索,直到两个位置相遇。 现在,您要删除的所有项目都在集合的末尾。 您可以在O(1)中删除所有它们。
从理论上讲,这两者的总体复杂度是相同的-均为O(N)。 但是,在许多情况下,复制项目是相对昂贵的(相对于仅确定是否保留该项目)。 这样可以最大程度地减少要复制/移动的项目的数量,因此,当复制/移动的成本很高时,可以节省大量时间(尽管,如前所述,如果其余对象的顺序很重要,则不合适)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.