摩尔投票法

简介: 摩尔投票法

提问:给定一个int型数组,找出该数组中出现次数大于数组长度一半的int值。

解决方案:遍历该数组,统计每个int值出现次数,再遍历该数组,找出出现次数大于数组长度一半的int值。

同样的,该解决办法也要求使用Map,否则无法达到线性的时间复杂度。

那么对于这个问题,有没有什么不使用Map的线性算法呢?

答案就是今天我们要提到的摩尔投票法。利用该算法来解决这个问题,我们可以达到线性的时间复杂度以及常量级的空间复杂度。

首先我们注意到这样一个现象:在任何数组中,出现次数大于该数组长度一半的值只能有一个。

通过数学知识,我们可以证明它的正确性,但是这并不在我们这篇博客里涉及。

摩尔投票法的基本思想很简单,在每一轮投票过程中,从数组中找出一对不同的元素,将其从数组中删除。这样不断的删除直到无法再进行投票,如果数组为空,则没有任何元素出现的次数超过该数组长度的一半。如果只存在一种元素,那么这个元素则可能为目标元素。

那么有没有可能出现最后有两种或两种以上元素呢?根据定义,这是不可能的,因为如果出现这种情况,则代表我们可以继续一轮投票。因此,最终只能是剩下零个或一个元素。

在算法执行过程中,我们使用常量空间实时记录一个候选元素c以及其出现次数f©,c即为当前阶段出现次数超过半数的元素。根据这样的定义,我们也可以将摩尔投票法看作是一种动态规划算法。

程序开始之前,元素c为空,f©=0。遍历数组A:

如果f©为0,表示截至到当前子数组,并没有候选元素。也就是说之前的遍历过程中并没有找到超过半数的元素。那么,如果超过半数的元素c存在,那么c在剩下的子数组中,出现次数也一定超过半数。因此我们可以将原始问题转化为它的子问题。此时c赋值为当前元素, 同时f©=1。

如果当前元素A[i] == c, 那么f© += 1。(没有找到不同元素,只需要把相同元素累计起来)

如果当前元素A[i] != c,那么f© -= 1 (相当于删除1个c),不对A[i]做任何处理(相当于删除A[i])

如果遍历结束之后,f©不为0,则找到可能元素。

再次遍历一遍数组,记录c真正出现的次数,从而验证c是否真的出现了超过半数。上述算法的时间复杂度为O(n),而由于并不需要真的删除数组元素,我们也并不需要额外的空间来保存原始数组,空间复杂度为O(1)。

看java代码示例,为了保证每一步骤的清晰性,代码没有经过优化。

640.png

其实这样的算法也可以衍生到其它频率的问题上,比如说,找出所有出现次数大于n/3的元素。同样可以以线性时间复杂度以及常量空间复杂度来实现。


目录
相关文章
|
7月前
|
存储 算法
摩尔投票的原理详解
摩尔投票的原理详解
168 1
|
7月前
DAY-3 | 摩尔投票法:巧求众数问题
LeetCode 链接:[Majority Element](https://leetcode.cn/problems/majority-element/)。这道题要求找到数组中出现次数超过数组长度一半的元素,也称为众数。文章介绍了使用摩尔投票法来解决此类问题,这种方法通过相互抵消的方式高效地找到多数元素。首先假设第一个元素是众数,然后遍历数组,遇到相同元素计数加一,不同元素计数减一,计数为零时更换假设的众数。最后计数不为零的元素即为众数。此外,还讨论了摩尔投票法的拓展应用和暴力统计的解法。
114 5
|
算法 JavaScript Android开发
LeetCode 周赛上分之旅 #33 摩尔投票派上用场
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
81 0
|
存储 算法
【趣学算法】贪心算法、海盗古董装船问题
贪心选择是指原问题的整体最优解可以通过一系列局部最优的选择得到,也就是先做出当前最优的选择,将原问题变为一个相似却规模更小的子问题,而后的每一步都是当前最优的选择。这种选择依赖于已做出的选择,但不依赖于未作出的选择。
|
算法 安全 区块链
白话讲解,拜占庭将军问题
作为服务端开发的同学,你可能听说过Paxos、Raft这类分布式一致性算法,也在工作中使用过ZooKeeper、etcd等工具来解决一致性问题。但你可能不知道,这些算法和工具解决的并不是一致性中最难的问题,要讨论这个最难的问题,这就要追溯到 Leslie Lamport 1982 年发表的著名论文 《拜占庭将军问题》(The Byzantine Generals Problem )上了。
白话讲解,拜占庭将军问题
|
存储 算法 JavaScript
你听说过摩尔投票法吗?
你听说过摩尔投票法吗?
282 0
你听说过摩尔投票法吗?
【LeetCode169】多数元素(摩尔投票法)
先用sort排序后,因为定义的“多数元素”是在数组中出现次数大于n/2的元素,所以可以返回下标为n/2的数组元素即所求。 用sort的时间复杂度就是O(nlogn)而非O(n)了。
100 0
【LeetCode169】多数元素(摩尔投票法)

热门文章

最新文章