首页 > 其他分享 >摩尔投票(绝对众数)

摩尔投票(绝对众数)

时间:2022-10-10 22:13:03浏览次数:61  
标签:候选者 cnt 遍历 摩尔 次数 投票 众数 出现

绝对众数:数组内出现次数大于 \(\lceil \cfrac{n}{2} \rceil\) 的数。

求绝对众数的方法:
暴力做法 \(O(n \log n)\) 排序并枚举左端点。

摩尔投票:\(O(n)\) 求出。

摩尔投票

image

丢个模板。


            int now = -1; int cnt = 0;
            f(j, 1, n) {
                if(x[j] != now) cnt--;
                else cnt++;
                if(cnt < 0) {
                    now = x[j]; cntx = 1;
                }
            }
            int ccnt = 0;
            f(j, 1, n) {
                if(x[j] == now) ccnt++;
            }
            if (ccnt >= len){
                cout << cnt << endl; 
            }   

注意,序列存在区间众数时,一定是 \(cnt\)。序列不存在区间众数时,\(cnt\) 随机。所以还要再扫一遍。

拓展到 n / k

https://leetcode.cn/problems/majority-element-ii/

可以证明,出现次数超过 \(n/k\) 的数最多只有 \(k - 1\) 个。否则必然违背「数总共只有 \(n\) 个」或者「当前统计的是出现次数超过 \(n / k\) 的数」的前提条件。

当明确了符合要求的数的数量之后,我们可以使用有限变量来代表这 \(k−1\) 个候选数及其出现次数。

然后使用「摩尔投票」的标准做法,在遍历数组时同时 check 这 \(k - 1\) 个数,假设当前遍历到的元素为 \(x\):

  • 如果 \(x\) 本身是候选者的话,则对其出现次数加一;
  • 如果 \(x\) 本身不是候选者,检查是否有候选者的出现次数为 \(0\):
    若有,则让 \(x\) 代替其成为候选者,并记录出现次数为 \(1\);
    若无,则让所有候选者的出现次数减一。
    当处理完整个数组后,这 \(k - 1\) 个数可能会被填满,但不一定都是符合出现次数超过 \(n / k\) 要求的。

需要进行二次遍历,来确定候选者是否符合要求,将符合要求的数加到答案。

上述做法正确性的关键是:若存在出现次数超过 \(n / k\) 的数,最后必然会成为这 \(k - 1\) 个候选者之一。

我们可以通过「反证法」来进行证明:若出现次数超过 \(n / k\) 的数 \(x\) 最终没有成为候选者。

有两种可能会导致这个结果:

数值 \(x\) 从来没成为过候选者:

如果 \(x\) 从来没成为过候选者,那么在遍历 \(x\) 的过程中,必然有 \(k - 1\) 个候选者被减了超过 \(n / k\) 次,假设当前 \(x\) 出现次数为 \(C\),已知 \(C>n/k\),此时总个数为

\((k - 1) * C + C = C * k\)

再根据 \(C > n / k\),可知 \(C * k > n\),而我们总共就只有 \(n\) 个数,因此该情况恒不成立。

数值 \(x\) 成为过候选者,但被逐出替换了:

同理,被逐出替换,说明发生了对 \(x\) 出现次数减一的动作(减到 \(0\)),每次的减一操作,意味着有其余的 \(k - 2\) 个候选者的出现次数也发生了减一动作,加上本身被遍历到的当前数 \(num[i]\),共有 \(k - 1\) 个数字的和 \(x\) 被一同统计。
因此,根据我们摩尔投票的处理过程,如果 \(x\) 成为过候选者,并被逐出替换,那么同样能够推导出我们存在超过 \(n\) 个数。

综上,如果存在出现次数超过 \(n / k\) 的数,其必然会成为 \(k−1\) 个候选者之一。

标签:候选者,cnt,遍历,摩尔,次数,投票,众数,出现
From: https://www.cnblogs.com/Zeardoe/p/16777614.html

相关文章

  • 【图解源码】Zookeeper3.7源码剖析,Session的管理机制,Leader选举投票规则,集群数据同步
    Zookeeper3.7源码剖析能力目标掌握Zookeeper中Session的管理机制能基于Client进行Debug测试Session创建/刷新操作能搭建Zookeeper集群源码配置掌握集群环境下Leader选举启动......
  • PVN3D: 基于Deep Point-wise 3D关键点投票的6D姿态估计网络(香港科技大学提出)
    论文链接:​​https://arxiv.org/pdf/1911.04231v1.pdf​​代码链接:​​https://github.com/ethnhe/PVN3D.git​​.背景介绍由于光照变化、传感器噪声、场景遮挡和目标截断等......
  • 普通莫队解决区间众数的个数
    SP32900KDOMINO-K-dominantarrayP1997faebdc的烦恼P3709大爷的字符串题被摩尔投票法洗脑半天,发现好像可以直接拿莫队写啊喂!针对原数据离散化,后开一个计数器和一......
  • 摩尔纹问题
    ue4中解决摩尔纹的建议是指贴图缩小后出来的随机条纹吗,那个大概是你的贴图每个像素差异太大密度又太高导致的,不建议把贴图上的噪波缩小到个位数像素的级别,适当模糊一下贴......
  • P7856 「EZEC-9」模糊众数 解题报告
    P7856「EZEC-9」模糊众数解题报告:题意给定一个长度为\(n\)的序列,一次操作可以将某个数字加一,多次询问一个数\(x\),求使得\(x\)称为序列众数至少要多少次操作。\(1......
  • 摩尔投票法学习笔记
    摩尔投票法绝对众数:数列内出现次数超过数列长度一半的数。摩尔投票法是一个求绝对众数的利器。例题1.洛谷P2397yyylovesMathsVI(mode)摩尔投票法板子题。假......
  • 主元素问题与摩尔投票法、格雷码
    一堆小玩意,放到一起。题意:给定一个n个元素数列,保证有一个数\(a\)的出现次数超过\(\lfloor\fracn2\rfloor\),求这个数。数据范围\(n<=3000000,a_i\le2147483647,\)时限0.......
  • NOI 2022 众数
    1.前言首先是:关于\(\rmdeque\),他死了但没有完全死。然后是这个大样例说实话有点离谱,最初我在写\(75\\rmpts\)部分分的时候,我动态开点线段树的\(\rminsert\),没......
  • 洛谷 P8496 [NOI2022] 众数 题解
    最近7年最水的D1T1。用权值线段树维护每个数出现的次数,链表维护序列。操作4即合并两棵权值线段树、两个链表,操作2就是删除链表尾的元素并在权值线段树上修改。显......