该算法用来寻找一个数组中出现次数超过1/k的元素,易得满足要求的元素最多有k-1个。
摩尔投票法分为两个阶段:抵消阶段和计数阶段。
抵消阶段:两个不同投票进行对坑,并且同时抵消掉各一张票,如果两个投票相同,则累加可抵消的次数;
计数阶段:在抵消阶段最后得到的抵消计数只要不为0,那这个候选人是有可能超过一半的票数的,为了验证,则需要遍历一次,统计票数,才可确定。
我们通过下面两道题来深入理解这个算法:
1.(寻找众数)
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋
的元素。
这道题方法很多:
1.首先我们可以在平方级的时间里穷举所有情况,来检测每个数是不是众数。不过时间复杂度为O(n2)。
2.其次我们可以对数组排序,然后选择中间元素,即为众数。如果使用快速排序时间复杂度为O(nlogn)。
3.我们这里用摩尔投票法怎么做呢?
我们只需维护一个计数器,如果遇到一个我们目前的候选众数,就将计数器加一,否则减一。只要计数器等于 0 ,我们就将 nums 中之前访问的数字全部忘记 ,并把下一个数字当做候选的众数。可用你还没理解,我们换句话讲,每次从数组中拿走2个不同的数,最后剩下的一定是众数。这样只需要进行一次遍历,因此时间复杂度为O(n)。下面是c++实现:
class Solution {
public:
int m