摩尔投票法——求众数
摩尔投票法:
出自论文:
https://www.cs.ou.edu/~rlpage/dmtools/mjrty.pdf
又称为多数投票法,摩尔投票法的一大应用就是求众数。
摩尔投票法基于这样一个事实,当一个数的重复次数超过数组长度的一半,每次将两个不相同的数删除,最终剩下的就是要找的数。
摩尔投票法分为两个阶段:抵消阶段和计数阶段。
抵消阶段:两个不同投票进行对坑,并且同时抵消掉各一张票,如果两个投票相同,则累加可抵消的次数;
计数阶段:在抵消阶段最后得到的抵消计数只要不为 0,那这个候选人是有可能超过一半的票数的,为了验证,则需要遍历一次,统计票数,才可确定。
算法步骤:
1.count = 0; num = nums[0]; 表示从此时开始计算投票。
2.遍历数组,如果接下来出现的数字与num相同,count加1。如果不同,count减1。
3.如果count == 0,表示之前出现的所有数字中num都是可以凑成不同的数对,一起抵消。大于1/2 n的数还会在后面出现。
4.如果count < 0,表示之前num中的数字没有到一半,所以此时完全不用考虑前面存储的元素,“删除”他们。直接从现在的新的元素开始计数,并令count = 0。
应用可见:LeetCode 169题 (21.3.30)
对于n/2的情况,最后剩的那个一定是众数(因为题目前提是必存在的情况
https://leetcode-cn.com/problems/majority-element/
拓展:
LeetCode 229题:给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 (21.3.30)
https://leetcode-cn.com/problems/majority-element-ii/
算法:每次删除三个不相同的数,最后留下的一定是出现次数超过1/3的数
这个思想可以推广到出现次数超过1/k次的元素有哪些
即:
至多选出m个代表,每个选票数大于n / (m + 1)
但需要注意的是,拓展的情况还需要验证一遍
参考文献:
https://blog.csdn.net/happyeveryday62/article/details/104136295
浙公网安备 33010602011771号