在 O(n) 时间内从容器中移除 <number> 个元素

Posted

技术标签:

【中文标题】在 O(n) 时间内从容器中移除 <number> 个元素【英文标题】:Remove <number> of elements from a container in O(n) time 【发布时间】:2013-02-20 00:28:43 【问题描述】:

假设您想实现一个模板化函数,该函数接受两个迭代器到一个容器和一个整数,该整数描述“如果容器中的元素在容器中的次数少于 次,则将其从容器中弹出”。这样的声明可以是:

template <class theIter>
theIter pop_um(theIter start, theIter end, int fewerThan);

是否可以在 O(n) 时间内编写这样的函数?执行此类任务通常使用哪些程序?

【问题讨论】:

是否有任何代码尝试这样做?无意冒犯,但这看起来像是一个家庭作业问题。 我从教科书中得到了这个问题(如推荐的那样),所以这不是特别的家庭作业。我很困惑如何在 O(n) 中完成移除;也就是如何快速判断哪些元素出现的次数少? 如果我有一个像 (2,3,2,4,4,5,5,5,5,6,7,4) 这样的向量,我想删除所有出现较少的元素怎么办超过 3 次(即删除 2、3、6 和 7)。如果我只是从头到尾,我怎么知道 2,例如,当我遇到它的第一个实例时只出现两次(没有遍历整个容器)? 更好的解决方案 - 扫描数组并保持结构中每个元素的运行计数。完成后,遍历您的计数数组并删除出现次数超过“less_than”次的元素。这将运行 O(2n * (num 匹配)) 时间,这将根据 num_matches 在线性和二次之间变化。这里的问题是虽然访问您的计数数组可以在恒定时间内完成,但不会重新扫描您的计数。此外,堆栈/列表样式的解决方案也无济于事,因为您必须在每次迭代时重新扫描它以查找以前的匹配项。 桶/基数排序您的数据以线性时间开始。然后以线性时间扫描您的新排序列表,跟踪元素何时更改并使其易于弹出。线性时间。 【参考方案1】:

桶/基数对您的数据进行排序(从开始到结束迭代器)以线性时间开始。然后以线性时间扫描您的新排序列表,跟踪元素何时更改并使其易于弹出。线性时间。 O(2n) = O(n)。虽然取决于您的排序方式,但会为存储桶占用大量 RAM。

【讨论】:

桶排序的时间复杂度不是O(n^2)吗? 另请注意,这不必包含整数。例如,它可以包含单词。 基数排序也可以在线性时间内对单词起作用,只是没有线性时间那么快。桶排序最坏情况os O(n ^ 2),而基数排序是线性的。在我看来,它们都很相似,这就是我一起提到它们的原因。我仍然很确定我的解决方案将在线性时间内起作用并坚持下去,直到其他人想出更好的东西。

以上是关于在 O(n) 时间内从容器中移除 <number> 个元素的主要内容,如果未能解决你的问题,请参考以下文章

从集合向量中移除集合

在 O(log(n)) 时间内从 std::set 中随机选择一个元素

一次通过在 O(n) 时间内从大量 URL 列表中找到唯一的 URL

Kubernetes容器集群管理环境 - Node节点的移除与加入

如何从一侧移除高程阴影而不从卡片或材质小部件中移除高程本身?

从 ListViewItem 中移除高亮效果