主元素
主元素的定义:
如果一个数组A[1..n]中超过半数的元素都相同时,该数组被称为含有主元素。
寻找主元素
- 那么如何寻找一个数组的主元素么?
直接寻找
虽然这是个笨方法,但笨方法也有他的好处:好懂,易写.
定义不是说了么,数量超过一半的数就是主元素,那么我们统计每个数出现的次数不就好了.
代码略
这个算法的时间效率为
改进
当已知元素的范围,我们可以用数组下标来对应元素,以快捷的统计元素的个数.
代码如下:
#define MAX 1000
int FindMainElement(int *Num,int N)
{
int Count[MAX]={0};
for(int i=0;i<N;i++)//统计个数
Count[Num[i]]++;
for(int i=0;i<N;i++)//找出主元素
if(Count[Num[i]]>=N/2)
return Count[Num[i]];
}
相比刚才的算法,时间效率变为
排序后寻找
既然已经知道了主元素一定多于
素一定是组元素,那么这种排列最常见的莫过于排序了.
那么接下来就很简单了.
代码略
算法的时间效率和空间效率由排序算法而定,那么我么可以知道,该种算法最好的是
灵光一现
有些算法无法用常用的算法思想来归纳他,他们往往来自脑海中一现的火花,令人深深折服.
以下算法来自于<编程之美>
//#######################################################################
//# Author: izualzhy@163.com
//# Description:
//#######################################################################
int FindMainElement(const int a[], const int Len)
{
int mainElement;
int repeatTimes = 0;
for ( int i=0; i<Len; ++i) {
if (repeatTimes==0) {
mainElement = a[i];
repeatTimes = 1;
} else {
if (a[i]==mainElement)
repeatTimes++;
else
repeatTimes--;
}
}
return mainElement;
}
如果你看不懂,那么看完下面这个小故事,你一定会懂:
主元素杯–最强团队争霸赛又开始了,一群团队摩拳擦掌,跃跃欲试,现在他们鱼贯而入,但是一点点意外,使他们的顺序发生了混乱,并非是按照同意团队入场,主办方想了个巧妙地方法,因为按夺冠的要求来看,胜出的团队人数一定大于等于参赛人数的一半,那么把每个参赛选手都变成相同的实力,那么只要不内斗,夺冠队伍一定可以打过其余的所有队伍,最后站在擂台上的最后一定就是夺冠队伍了,最终这一届争霸赛成功举办,大家纷纷赞叹主办方的机智.
补充
有种主元素的定义包括了半数的情况,这将带来非常麻烦的情况:
只要半数就可以了,那么是如下情况呢?
1 1 1 1 0 0 0 0
那么谁是主元素呢?
这样的话解决这个问题就麻烦的多,至少函数可能不能传回一个数,那么遇到这种情况,请大家发挥自己找出最合适的方法吧.