寻觅主元素

无意中找到了这篇讲解如何寻找主元素的文章,写得很好,分享一下:http://www.myexception.cn/mobile/1444062.html

寻找主元素

问题分析:所谓找主元素,就是在一个整数序列(数组)中,里面的某一个元素出现的次数超过元素总个数的一半,那么就陈这个元素为主元素。

性质1: 如果存在主元素的话,主元素一定是中位数

方法1:

使用快排O(nlogn)进行排序,找到中位数,然后判断首元素是否和中位数相等、以及尾元素是否和中位数相等。 如果有一个以上的相等,则存在主元素(中位数)。

方法2:

使用O(n)的选择算法找到中位数,然后再判断中位数是不是主元素。

方法3:

性质2:如果一个数组中有主元素,则同时删除两个不相等的值,这个序列中的主元素不会改变

其中比较好的解决方法是第三种,其实现可用递归,也可用迭代,下面代码分别给出其实现:

递归实现:

//a表示数组,len表示数组长度,num用于递归
int candidate(int *a,int len,int num)
{
    int j = num;
    int c = a[num];
    int counts = 1;
    while(j<len && counts>0)
    {
        j++;
        if(a[j] == c) counts++;
        else counts--;
    }
    if(j == len) return c;
    else candidate(a,len,j+1);
}

void majority_1(int *a,int len)
{
    int c = candidate(a,len,0);//注意数组下标是从0开始,所以递归也从0开始
    int counts = 0;
    for(int j = 0;j<7;j++)
    {
        if(a[j] == c) counts++;
    }
    if(counts > 7/2) cout<<c<<endl;
    else
    {
        cout<<"none"<<endl;
        return;
    }
}



迭代实现:

void majority_2(int *a, int len)
{
    int seed = a[0];
    int count = 1;

    for (int i = 1; i < len; i++)
    {
        if (seed == a[i])
            count++;
        else
        {
            if (count == 0)
            {
                seed = a[i];
                count = 1;
            }
            else
                count--;
        }
    }

    // justify seed..
    count = 0;
    for (int i = 0; i < len; i++)
    {
        if (a[i] == seed)
            count++;
    }
    if (count > len/2)
        cout<<seed<<endl;
    // no main elements in the array...
    else cout<<"none"<<endl;

}



测试示例:

int main()
{
    int a[7] = {1,2,3,1,2,1,1};
    majority_1(a,7);
    majority_2(a,7);
    return 0;
}


结果都是输出:1

原文地址:https://www.cnblogs.com/smilehuanxiao/p/3415370.html