1.问题描述
对于一个大小为N的整数数组,将其中出现次数大于N/2的元素称为主要元素,例如{5,5,6,6,5,7,5,5}中主要元素是5,而{5,6,5,6,5,6,5,6}中则没有。
2.思路
似乎是一个统计数组元素出现次数的问题,因此寻找出现次数最多的元素的解法在这里也适用。
不过该问题有一个特点:即要求元素出现次数过半。因此,如果存在这样的主要元素X,将它与数组所有元素进行比较,相等则将一计数器(初始化为0)+1否则-1,这样相消相杀后计数器必然大于0。
但现实是并不知道这个主要元素X是多少,那么可以先假设X为数组中任意元素,并先将这个假设的X与第一个元素进行比较,相等则将计数器(初始化为0)+1否则将第一个元素设为X,继续与第二个元素比较,相等则将计数器+1否则-1,若此时计数器为0不够减,则将X设为第二个元素继续与下个元素比较,依次类推......直到最后一个元素。最终的X即为主要元素。
在假定存在主要元素时,我们可以得到这样一个X,再遍历一次数组便可验证其是否真的存在。
3.代码
#include <stdio.h> int majorElement(int array[],int N); int main(void) { //测试用例 int array1[8]={2,1,2,3,2,4,2,2}; int array2[7]={2,1,2,3,2,4,2}; int array3[8]={1,1,1,2,2,2,2,2}; int array4[8]={2,2,1,1,1,2,2,2}; int array5[8]={2,2,1,1,1,1,2,2}; printf("%d %d %d %d %d\n",majorElement(array1,8),majorElement(array2,7),\ majorElement(array3,8),majorElement(array4,8),majorElement(array5,8)); return 0; } int majorElement(int array[],int N) { int X=array[0];//假定X为任意数组元素,这里取第一个元素 int cnt=0;//初始化计数器counter int i; //假定存在主要元素X for(i=0;i<N;i++) { if(X==array[i]) cnt++; else if(0==cnt) X=array[i]; else cnt--; } //验证是否真的存在 for(i=0,cnt=0;i<N;i++) if(X==array[i]) cnt++; if(cnt>N/2) return X; return 0x80000000;//不存在则返回一最大的负数 }