如何有效地收集给定数组中的重复元素?

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) 空间更好。

【讨论】:

以上是关于如何有效地收集给定数组中的重复元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地改变矩阵的连续部分?

确定数组中的重复值

React:给定一个数组,以相反的顺序有效地渲染元素

有效地计算numpy数组中的零元素?

算法:从数组中删除重复整数的有效方法

删除排序数组中的重复项