查找在线性时间内出现超过n / 4次的所有元素

时间:2014-07-11 06:06:23

标签: arrays algorithm search

这个问题是Skiena的4-11。找到多数元素的解决方案 - 重复超过一半是多数算法。我们可以用它来找到重复n / 4次的所有数字吗?

4 个答案:

答案 0 :(得分:3)

Misra and Gries描述了几种方法。我不完全理解他们的论文,但一个关键的想法是使用一个包

Boyer and Moore's original majority algorithm paper有许多难以理解的证据和对FORTRAN代码的形式验证的讨论,但它有一个非常好的 start 解释多数算法如何工作。关键概念首先要考虑的是,如果大多数元素都是A并且您一次删除一个,A的副本和其他内容的副本,那么最终您将只有A的副本。接下来,应该清楚的是,删除两个不同的项目A,只能增加A占有的多数。因此,只要它们不同,就可以安全地删除任何项目。然后可以使这个想法具体化。从列表中取出第一个项目并将其粘贴在一个盒子中。取出下一个项目并将其粘在盒子里。如果它们相同,那就让它们都坐在那里。如果新的不同,请将其与盒子中的项目一起扔掉。重复此操作,直到所有项目都在框中或垃圾箱中。由于该框仅允许一次包含一种项目,因此可以非常有效地将其表示为(item type, count)对。

查找可能超过n/k次的所有项目的概括很简单,但解释其工作原理有点困难。基本思想是我们可以在不改变任何内容的情况下找到并销毁k 不同元素的组。为什么?如果w > n/kw-1 > (n-k)/k。也就是说,如果我们拿走其中一个受欢迎的元素,并且我们也会删除k-1 其他元素,那么流行的元素仍然很受欢迎!

实施:不要仅在框中允许一种类项目,而是允许k-1项。每当您看到一组k 个不同的项目出现时(也就是说,框中有k-1个类型,并且到达的那些不匹配任何他们),你扔垃圾桶中的每一种,包括刚刚到达的那种。我们应该为这个"框使用什么数据结构?#34;?好吧,一个包,当然!正如Misra和Gries所解释的,如果可以对元素进行排序,那么具有O(log k)基本运算的基于树的包将使整个算法具有O(n log k)的复杂度。需要注意的一点是,删除每个元素之一的操作是昂贵的(我认为是O(k log k)),但是这些成本是在这些元素的到达时分摊的,所以这没什么大不了的。当然,如果你的元素是可清洗的而不是可订购的,你可以使用基于散列的包,这在某些常见的假设下会提供更好的渐近性能(但不能保证)。如果你的元素是从一个小的有限集中绘制出来的,你可以保证。如果他们只能比较 equality ,那么你的行李会变得更加昂贵,而且我很确定你最终会得到类似O(nk)的东西。

答案 1 :(得分:2)

有关使用常量内存并以线性时间运行的解决方案,请参阅this paper,这将找到3个候选元素,这些元素出现的次数超过n / 4次。请注意,如果您假设您的数据是以流式形式提供的,您只能进行一次,这是您可以做的最好的事情 - 您必须再次通过该流来测试3个候选者中的每一个以查看是否它在流中发生超过n / 4次。但是,如果您假设有3个元素出现超过n / 4次,那么您只需要通过流一次,这样您就可以获得线性时间在线算法(仅通过流一次),只需要不变存储

答案 2 :(得分:2)

通过 Moore-Voting算法找出n/2 times显示的多数元素

参见Moore的投票算法(http://www.geeksforgeeks.org/majority-element/)给定链接的方法3。

<强>时间:O(n)的

现在找到多数元素后,再次扫描数组并remove the majority element或将其-1.

<强>时间:O(n)的

现在对阵列的其余元素应用摩尔投票算法(但现在忽略-1,因为它已经包含在前面)。新的多数元素显示为n/4 times.

<强>时间:O(n)的

总时间:O(n)

额外空间:O(1)

你可以为出现超过n / 8,n / 16,......时间

的元素做到这一点

修改

可能存在数组中没有多数元素的情况:

例如如果输入数组为{3, 1, 2, 2, 1, 2, 3, 3},则输出应为[2, 3]

给定大小为n且数字为k的数组,找出出现次数超过n / k次的所有元素

请参阅此链接以获取答案: https://stackoverflow.com/a/24642388/3714537

参考文献:

http://www.cs.utexas.edu/~moore/best-ideas/mjrty/

答案 3 :(得分:0)

由于你没有提到空间复杂性,一种可能的解决方案是使用hashtable作为映射到count的元素,然后只要找到元素就可以增加计数。