摩尔投票法
作者:互联网
知乎简介
首先请考虑最基本的摩尔投票问题,找出一组数字序列中出现次数大于总数1/2的数字(并且假设这个数字一定存在)。显然这个数字只可能有一个。摩尔投票算法是基于这个事实:每次从序列里选择两个不相同的数字删除掉(或称为“抵消”),最后剩下一个数字或几个相同的数字,就是出现次数大于总数一半的那个。
形象化描述
想象着这样一个画面:会议大厅站满了投票代表,每个都有一个牌子上面写着自己所选的候选人的名字。然后选举意见不合的(所选的候选人不同)两个人,会打一架,并且会同时击倒对方。显而易见,如果一个人拥有的选票比其它所有人加起来的选票还要多的话,这个候选人将会赢得这场“战争”,当混乱结束,最后剩下的那个代表(可能会有多个)将会来自多数人所站的阵营。但是如果所有参加候选人的选票都不是大多数(选票都未超过一半),那么最后站在那的代表(一个人)并不能代表所有的选票的大多数。因此,当某人站到最后时,需要统计他所选的候选人的选票是否超过一半(包括倒下的),来判断选票结果是否有效。
解读
- 减治(通过不断地消去不同的元素来缩小数组元素区间)
- 通过抵消掉最后的数不一定是众数,仍需判断(这里众数的定义是超过数组一半个数的数)
例题:LeetCode面试题17.10
数组中占比超过一半的元素称之为主要元素。给定一个整数数组,找到它的主要元素。若没有,返回-1。
要求时间复杂度 O(N),空间复杂度O(1)
int majorityElement(vector<int>& nums) {
int major,cnt=0; //major代表众数 cnt计数
for(int x:nums){
if(cnt==0){
major=x;
cnt++;
}
else{
if(major==x)
cnt++;
else
cnt--;
}
}
if(cnt>0){
int t=0;
for(int x:nums){
if(x==major)
t++;
}
if(t>nums.size()/2) //仍需加以判断
return major;
}
return -1;
}
参考链接
知乎链接:https://www.zhihu.com/question/49973163
博客链接:https://blog.csdn.net/happyeveryday62/article/details/104136295
标签:cnt,数字,nums,int,major,摩尔,选票,投票 来源: https://blog.csdn.net/qq_43477024/article/details/111652936