• 主元素问题


    主元素问题是一道非常经典的著名的问题,乍一看很简单,也很容易写出来,但越往后越难。

    问题描述:给定一个长度为n的序列,若当中有数出现的次数>50%,输出这个数;否则输出NO。

    还是先上数据:

    7

    3 3 1 1 3 2 3

    输出是:

    3

    有什么好的方法吗?

    建议你花时间先想一想

    好啦,开始讲解。

    Algorithm1:

    将数组进行排序,堆排序或者快速排序,然后找出n/2+1那个位置的数。然后再扫一遍,统计这个数出现的次数。若该次数>n/2,那么这个数就是结果,否则输出NO。

    原理:如果有数出现的次数>n/2,那么排序后,它一定会出现在n/2+1的位置上(想一想为什么)。

    时间复杂度:O(N log N)

    空间复杂度:O(N)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n,a[1005],i,cnt; 
    int main()
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        for(i=1;i<=n;i++)
            if(a[i]==a[n/2+1]) cnt++;
        if(cnt>n/2) printf("%d",a[n/2+1]);
            else printf("NO");
        return 0;
    }
    Algorithm1

    Algorithm2:

    用类似桶排序的方法,开一个数组储存每个数出现的次数。然后再扫一遍,找出那个出现次数最多的数,看看是否>n/2。

    这种算法比较好理解。

    时间复杂度:O(N+M)

    空间复杂度:O(M)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n,a,x[100005],i,m=-9,cnt=-9,ans;
    int main()
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a);
            x[a]++;
            if(m<x[a]) m=x[a];
        }
        for(i=1;i<=m;i++)
            if(x[i]>ans) 
            {
                cnt=x[i];
                ans=i;
            }
        if(cnt>n/2) printf("%d",ans);
        else printf("NO");
        return 0;
    }
    Algorithm2

    Algorithm3:

    O(N)的算法来啦!

    绝妙的思想:这样的算法有一个性质:如果在原数组中删除两个不同的数,那么在原数组中出现次数超过50%的数,在新数组中的次数也一定会超过50%。

    仔细想一想为什么吧!一旦掌握了这种方法,那么此题就简单了。强烈建议读者自己用这种方法完成此题。

    时间复杂度:O(N)

    空间复杂度:O(N)

    代码也给你们吧:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n,a[1005],x,y,i;
    int main()
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(y==0)
            {
                x=a[i];
                y++;
            }
            else
            {
                if(x==a[i]) y++;
                else y--;
            }
        }
        y=0;
        for(i=1;i<=n;i++)
            if(a[i]==x)
                y++;
        if(y>n/2) printf("%d",x);
        else printf("NO");
        return 0;
    }
    Algorithm3


    再强调一遍:强烈建议读者完成此题,并想明白所有细节。

    ~祝大家编程顺利~

  • 相关阅读:
    Linux--echo输出内容到控制台
    Web前端基础(14):jQuery基础(一)
    Web前端基础(13):JavaScript(七)
    Web前端基础(12):JavaScript(六)
    Web前端基础(11):JavaScript(五)
    Web前端基础(10):JavaScript(四)
    Web前端基础(9):JavaScript(三)
    Web前端基础(8):JavaScript(二)
    Web前端基础(7):JavaScript(一)
    Web前端基础(6):CSS(三)
  • 原文地址:https://www.cnblogs.com/llllllpppppp/p/7607671.html
Copyright © 2020-2023  润新知