摩尔投票法
1.原理
1.1形象化描述
会议大厅站满了投票代表,每个都有一个牌子上面写着自己所选的候选人的名字。然后选举意见不合的(所选的候选人不同)两个人,会打一架,并且会同时击倒对方。显而易见,如果一个人拥有的选票比其它所有人加起来的选票还要多的话,这个候选人将会赢得这场“战争”,当混乱结束,最后剩下的那个代表(可能会有多个)将会来自多数人所站的阵营。但是如果所有参加候选人的选票都不是大多数(选票都未超过一半),那么最后站在那的代表(一个人)并不能代表所有的选票的大多数。因此,当某人站到最后时,需要统计他所选的候选人的选票是否超过一半(包括倒下的),来判断选票结果是否有效。
1.2算法步骤
对抗阶段
设立一个计数器cnt=0。不断去判断数组中的元素,如果cnt=0,则将当前元素加入阵营,cnt++.反之cnt>0,则需判断是否属于同一阵营,是则+不是则-;
统计阶段
最后剩余的阵容的候选人,不一定就是人数最多的(可能不存在主元素,群雄乱战),则还需要判断该阵营人数是否>总人数的一半。
1.3伪代码
2.例题及代码
eg. leetcode 面试 17.10 :求一维数组中存在主元素(主元素是指该元素在数据出现个数m超过数组长度的一半 m>n/2)
class Solution {
public:
int majorityElement(vector<int>& nums) {
//摩尔投票法
int cnt=1,n=nums.size();
int mainElem=nums[0];//统计数量 初始化为数组首个字母
for(int i=1;i<n;i++){
if(nums[i]==mainElem)
cnt++;
else
if(cnt>0){
cnt--;
}
else{
mainElem=nums[i];
cnt++;
}
}
//判断之后还得统计元素个数是否大于一半 !剩下的元素 如果个数大于一半,肯定就主元素
if(cnt>0){
cnt=0;
for(auto num :nums){
if(num==mainElem)
cnt++;
}
}
if(cnt>(n/2))return mainElem;
return-1;
}
};