一、什么是主元素

在一个数列中出现次数超过50%的数。
例如:3、3、4、3、2、1、3中主元素就是3.

二、怎么求主元素

现给定一个序列,其中有主元素。

方法一:分别记录每个数出现的次数

用一个数组记录每个数出现的次数,就是类似桶排序的方法,数组中次数超过总数一半的那个数就是要求的主元素。

#include <bits/stdc++.h>
using namespace std;
int ans[10001],n,t;
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>t;
        ans[t]++;
    }
    for(int i=0;i<10001;i++)
        if(ans[i]>n/2)
        {
            cout<<i;
            break;
        }
    return 0;
}

时间复杂度与空间复杂度都为O(N+M)。
如果跨度很大,可以离散化一下。

方法二:排序后位置为N/2+1的数

如果一个数列中含有主元素,那么排序后主元素就是位于N/2+1位置的数。
举例1:3、3、4、3、2、1、3 -> 1、2、3、3、3、3、4
举例2:3、3、3、3、5、3、1、0 -> 0、1、3、3、3、3、3、5

#include <bits/stdc++.h>
using namespace std;
int n,a[10001];
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[n];
    sort(a,a+n);//C++ STL自带排序函数
    cout<<a[n/2+1-1];//减1是因为这里数组从a[0]开始用
    return 0;
}

当然也可以用其他排序算法。
sort函数的时间复杂度是O(NlogN),总的复杂度为O(NlogN+N)。

方法三:运用含主元素序列的特性

含主元素序列的特性:在序列中去除两个不同的元素,主元素依然存在。
也就是说:进行多次去掉两个不同元素的操作后,剩下的一个或多个相同的数就是要求的主元素。
举例:3、3、4、3、2、1、3 -> 3、3、2、1、3 -> 3、1、3 -> 3
这里在输入时判断与上一次保存的输入是否相同,如不同则删除两数,这里用栈来实现。

#include<bits/stdc++.h>
using namespace std;
int n,q[10001],top=0,a;
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a;
        q[top++]=a;
        if(top!=1&&(q[top-1]!=q[top-2]))
            top-=2;
        
    }
    cout<<q[top-1];
    return 0; 
}

时间复杂度为O(N)。
终极压行版:

#include<stdio.h>
int n,q[10001],top=0,a;
int main()
{
    scanf("%d",&n);
    while(n--)scanf("%d",&a),q[top++]=a,top=(top>1&&(q[top-1]!=q[top-2]))?top-2:top;
    printf("%d",q[top-1]);
}

版权声明:本文为include-blog原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/include-blog/p/12389954.html