假设一个数列中有N个数,若某个数X在数列中的个数大于N/2(这里对N/2向下取整),则X为该数列的多数元素。那么怎样求多数元素呢?最简单的方法当然是暴力求解,用第一个数去和所有数比较,得出该数的个数,再依次用后面的数去比较,这样做的时间复杂度是O(N^2),没有讨论的必要,这里介绍一种时间复杂度只要O(N)的算法。
该算法的中心思想是:原数列中去除两个不同元素后,那么原数列中的多数元素在新数列中还是多数元素。
给定一个数组A[1..N],下面给出该算法的实现:
int candidate(int i)
{
int j=i; //i为数组下标,表示现在所在的位置
int c=A[i];
int count=1; //count是元素c的计数器
while( j0 )
{
j++;
if( A[j]==c ) count++; //c的个数加一
else count--; //这里表示取出两个不同的元素,多数元素不会改变
}
if( j==n ) return c;
else return candidate(j+1);
}
该函数返回的c即为多数元素的候选者,该数仍需通过验证。因为有可能出现类似1,3,1,3,2这样的数列,candidate函数在相继取出两对不同元素1,3,1,3后会返回最后一个数2,但此时2明显不是多数元素,故需要验证,验证函数很简单:
int test()
{
int c=candidate(1);
int count=0;
for( int i=1 ; i<=N ; i++ )
{
if( A[i]==c ) count++;
}
if( count>N/2 ) return c;
else return none;//表示没有找到多数元素
}
在执行完上面两个函数后就可以知道该数组是否存在多数元素了。