【问题标题】:Count occurrences in an array in O(n log n) time在 O(n log n) 时间内计算数组中的出现次数
【发布时间】:2020-04-30 18:43:40
【问题描述】:

给定一个未排序的数组A[],其中包含n 整数,如何创建一种算法来返回最常出现的元素?

我认为您需要一种方法来计算元素出现的次数。我只能找出一个 O(n2) 实现。我知道我需要先使用排序算法,但如果我要使用归并排序,那已经是 O(n logn)) 的总运行时间了。我只对数据进行了排序,如果不进一步增加运行时间,我就无法查看元素。

【问题讨论】:

  • 如果可以对数组进行排序,则归并排序可以达到 n logn 的效果,之后简单的 n 迭代就可以达到目的
  • 不是答案,而是线索。 O(n log n) + O(n) 仍然是 O(n log n)。 Big-O 表示法只关心主导项。
  • @DavidC 我以为你会把它们相乘——而不是相加!如果知道这一点,我就不会问这个问题了。谢谢!

标签: algorithm big-o


【解决方案1】:

对数组进行排序,然后,所有重复元素彼此相邻。
简单地迭代数组,同时持有maxSeencurrSeen 计数器,如果当前元素等于最后一个元素,则增加currSeen,否则 - 重置currSeen,如果currSeen 是则替换maxSeen比它大。

排序是O(nlogn),迭代一次是O(n),所以总共O(nlogn + n) = O(nlogn)

这是家庭作业,因此您应该按照本指南创建代码。祝你好运!


附带说明,因为这至少与使用基于比较的算法的Element Distinctness Problemit cannot be done better than O(nlogn) 一样难。


旁注二,可以使用哈希表在O(n) 时间+空间中完成。
创建数据的直方图,这是一个哈希映射,其中键是一个元素,值是出现次数。然后,问题衰减到在这个哈希表中找到最大值。
建表是O(n)平均情况,求最大值是O(n)

然而,这会使用O(n) 额外的内存,并且在最坏的情况下可能会恶化到O(n^2) 时间。

【讨论】:

  • 我没有听说过元素区别问题。感谢您提供该链接!
  • @templatetypedef 同样看第二个链接,它指向使用代数树模型证明下界的文章。 (当然它可以在 O(n) 平均情况和空间中完成,使用哈希,但不使用比较)
【解决方案2】:

您猜对了,从对数组进行排序开始是个好主意。正如您所指出的,这会花费 O(n log n)。然后,您可以扫描数组并逐个计算每个值的频率,同时记住最频繁的值。这需要 O(n)。总成本为O(n log n + n),在O(n log n)中。

要了解原因,请考虑 O(2n log n)。这肯定在 O(n log n) 内,因为 2n log nn log n 的常数因子内。而n log n + n在上面是2n log n,所以也在O(n log n)中。

【讨论】:

  • 我没有意识到您会将两个运行时相加,而不是相乘。那是我愚蠢。我很感激!
【解决方案3】:

只需将字典存储其中的每个数字作为键,并将值作为其计数,如果数字再次重复增加该计数,则初始值为 1,否则将其输入到字典中。

遍历字典中的每个键值,值较大的它的键将是最大的

解于n+n =2n ~> n

【讨论】:

  • 请注意,这是一个已有 4 年历史的问题,答案已被接受。并且 hashmap/dictionary 建议已包含在已接受的答案中。
猜你喜欢
  • 1970-01-01
  • 2015-06-29
  • 2016-04-09
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 2019-04-29
  • 2011-07-09
  • 2020-01-22
相关资源
最近更新 更多