摩尔投票算法
简介
引入
若一个大小为 n 的整数序列 ,若存在一个数字 x 在这个序列中出现的次数大于 ,那么称 x 为这个序列的主元素。
理解
摩尔投票算法是基于这个事实:
每次从序列里选择两个不相同的数字删除掉(或称为“抵消”),最后剩下一个数字或几个相同的数字,就是出现次数大于总数一半的那个。
或者更形象一点:
几个国家一起打架,假设你方人数超过总人数一半以上,并且能保证每个人出去干仗都能一对一同归于尽。不论是其他国家都联合起来对付你,或者其他国家也存在相互攻击的情况,只要你方不要内斗,最后肯定都是你赢。
实现
int Majority(int A[],int n)
{
int i,c,count=1;
c=A[0];
for(i=1;i<n;i++)
{
if (A[i]==c)
count++;
else
{
if(count>0)
count--;
else
{
c=A[i];
count=1;
}
}
}
if (count>0)
for(i=count=0;i<n;i++)
if(A[i]==c) count++;
if (count>n/2) return c;
else return -1;
}
扩展
一个大小为 n 的整数序列,最多存在(k - 1)种数字在序列中出现的次数大于 。
以 k = 3 为例
void Majority(int A[],int n)
{
int i,n1=A[0],count1=1,n2=A[1],count2=1;
for(i=2;i<n;i++)
{
if (A[i] == n1) count1++;
else if(A[i] ==n2) count2++;
else if(count1==0)
{
n1=A[i];
count1=1;
}
else if(count2==0)
{
n2=A[i];
count2=1;
}
else
{
count1--;
count2--;
}
}
for(i=count1=count2=0;i<n;i++)
{
if(A[i]==n1)
count1++;
else if(A[i]==n2)
count2++;
}
if(count1>n/3) printf("%d",n1);
if(count2>n/3) printf("%d",n2);
}