如何有效地收集给定数组中的重复元素?
Posted
技术标签:
【中文标题】如何有效地收集给定数组中的重复元素?【英文标题】:How to efficiently gather the repeating elements in a given array? 【发布时间】:2020-05-21 11:44:34 【问题描述】:我想收集给定数组中的重复项。例如,我有一个这样的数组:
1,5,3,1,5,6,3
我希望结果是:
3,3,1,1,5,5,6
在我的情况下,计算前不知道簇的数量,不关心顺序。
我通过使用 C++ 中的内置函数 Sort 实现了这一点。然而,实际上订购不是必需的。因此,我想可能有更有效的方法来完成它。
提前致谢。
【问题讨论】:
如果您只是想知道每个组中有多少个元素,那么可以使用 O(n),直方图方法。如果您确实需要对元素进行分组,那么我认为您需要进行排序。 在什么情况下需要这样做?例如,如果这是在课堂上作为作业给出的内容,那么您很可能需要使用在课堂上介绍过的特定技术,而做其他事情可能会导致您的作业失败。 您可以使用散列std::unordered_map
在 O(n) 中完成此操作,但实际上它仅适用于非常大的尺寸会更有效
@SamVarshavchik 谢谢,示例是简化版。在实践中,我将一个函数映射到元素并通过函数的结果收集它们。
@RichardCritten 谢谢你的回复,其实我不需要知道每组元素的数量。在实践中,元素不仅是通过它们的值收集的,而且是应用到它们的函数的结果。排序是一个不错的方法,而我正在尝试寻找一种更有效的方法。
【参考方案1】:
首先,构建一个直方图,记录每个数字的频率。您可以使用字典在 O(n) 时间和空间内完成此操作。
接下来,遍历字典的键(顺序在这里并不重要),并为每个键写入与相应值相等的该键的实例数。
例子:
1,5,3,1,5,6,3 input
1->2,5->2,3->2,6->1 histogram dictionary
1,1,5,5,3,3,6 wrote two 1s, two 5s, two 3s, then one 6
这整件事是 O(n) 时间和空间。当然,你不能比 O(n) 时间做得更好。在保持 O(n) 时间的同时,你是否可以做得比 O(n) 空间更好。
【讨论】:
以上是关于如何有效地收集给定数组中的重复元素?的主要内容,如果未能解决你的问题,请参考以下文章