此问题是Skiena的4-11。找到多数元素的解决方案 - 重复超过半数是多数算法。我们可以用它来找出所有重复n/4次的数字吗?查找在线性时间内出现超过n/4次的所有元素
回答
正如你没有提及空间复杂性,一个可能的解决方案是使用hashtable作为映射到计数的元素,然后你可以增加计数,如果找到元素。
请参阅http://www.cs.yale.edu/homes/el327/datamining2011aFiles/ASimpleAlgorithmForFindingFrequentElementsInStreamsAndBags.pdf了解使用常量内存并在线性时间内运行的解决方案,该解决方案将为发生超过n/4次的元素找到3个候选项。请注意,如果您假设您的数据是以只能通过一次的流的形式提供的,那么这是您可以做的最好的 - 您必须再次通过该流以测试3个候选人中的每一个以查看是否它在流中出现超过n/4次。然而,如果你先假设有3个元素发生的次数超过n/4次,那么你只需要经过一次流,这样你就可以得到一个线性时间在线算法(只经过一次流),只需要一个常量存储。
查找,通过摩尔定律表决权算法
给定的链接,Moore的投票算法中(http://www.geeksforgeeks.org/majority-element/)的方法见3出现n/2 times
大部分元素。
时间: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
参考文献:
Misra and Gries描述了几种方法。我不完全了解他们的论文,但一个关键的想法是使用一袋。
Boyer and Moore's original majority algorithm paper有很多难以理解的样张和Fortran代码正式verificatiom的讨论,但它的大部分算法如何工作的解释非常好的开始。关键概念始于如果大多数元素是A
,并且您一次删除一个A
副本和其他副本,那么最终您将只拥有A
的副本。接下来,应该清楚的是,移除两个不同的项目,两个都不是A
,只能增加A
所持有的多数。因此,只要它们不同,删除任意项都是安全的。这个想法可以被具体化。将第一个项目从列表中取出并粘贴在一个盒子中。把下一件物品拿出来放在箱子里。如果他们一样,让他们都坐在那里。如果新的是不同的,请将其与盒子中的物品一起扔掉。重复,直到所有项目都在箱子或垃圾箱中。由于箱子一次只允许有一种物品,因此它可以非常有效地表示为(item type, count)
。
查找所有可能出现的时间超过n/k
次的项目的概括很简单,但解释它的工作原理有点困难。基本的想法是,我们可以找到并摧毁k
不同的元素组而不改变任何东西。为什么?如果w > n/k
然后w-1 > (n-k)/k
。也就是说,如果我们拿走其中一个流行元素,而且我们还带走k-1
其他元素,那么流行元素仍然很受欢迎!
执行:取代只允许一个种类的项目在框中,允许k-1
其中。每当你看到一组k
不同的项目出现(也就是说,有k-1
类型在框中,并且到达的不匹配任何一个),你扔垃圾中的每种类型之一,包括一个刚刚到达。我们应该为这个“盒子”使用什么数据结构?好吧,当然是一个包!正如Misra和Gries所解释的那样,如果元素可以被排序,那么一个具有O(log k)基本操作的基于树的包就会给整个算法的复杂度为O(n log k)。需要注意的一点是,删除每个元素之一的操作是昂贵的(我认为O(k log k)),但是这些成本是在这些元素的到达之间分摊的,所以没什么大不了的。当然,如果你的元素是可散列的而不是可订购的,你可以使用基于散列的包,而在某些常见的假设下,它可以提供更好的渐近性能(但不能保证)。如果你的元素是从一个有限的小集合中抽取的,你可以保证这一点。如果他们只能比较等于,那么你的包变得更加昂贵,我敢肯定,你最终会得到类似O(nk)的东西。
- 1. 查找出现超过n/k次的所有元素
- 2. 线性时间,恒定空间算法,用于查找在列表中出现1次的元素
- 3. 查找出现奇数次的元素
- 4. 查找出现在所有给定的数组中的元素
- 5. 查找区域内的所有元素
- 6. 在Python中查找矩阵中所有元素的出现
- 7. 每次出现父元素时首次出现元素
- 8. 在线性时间内查找树中所有节点的最大距离
- 9. Scheme - 查找列表元素出现的所有索引
- 10. 查找名称空间内的所有元素
- 11. 通过属性使用Python查找ElementTree中的所有元素
- 12. 通过javascript查找元素时出错
- 13. 在SQL数据库中查找元素的第一次出现
- 14. 查找在log(n)时间内排序数组中至少出现k次的元素
- 15. 查找所有元素通过id属性
- 16. 在matlab中查找单元格内模式的出现次数?
- 17. Selenium - Python设置查找元素的超时时间
- 18. 查找在某个列中出现多次值的所有行
- 19. 查找所有元素共有的值
- 20. jQuery - 查找元素的第n次出现
- 21. 查找仅出现一次的第一个元素
- 22. 如何查找grails中每个元素的出现次数?
- 23. 查找数组列表中出现特定元素的次数
- 24. 查找列表中存在超过k次的所有元素的最佳方法
- 25. XSLT过程第一次出现元素
- 26. 在元素后出现的所有元素的选择器
- 27. 查找具有某一类的div内的所有元素
- 28. 硒查找具有特定属性的所有元素
- 29. 查找具有属性的所有元素
- 30. 获取所有只出现一次的元素
练习可能会要求使用n/2方法的思想,而不是算法作为子例程。 –
[查找是否有元素重复n/k次](https://stackoverflow.com/questions/3001181/find-if-there-is-an-element-repeating-itself-nk-times ) – dfeuer