• 主元素问题的多种解法


    Part -1:版权声明:

    本文大部分代码来自这篇博文

    Part 0:啥是主元素问题

    给一个有(n)个元素的数列,保证有一个数(a)出现的次数超过50%,求这个数

    Part 1:桶计数做法

    桶计数做法是出现一个数,就把这个数出现次数+1,很好懂:

    #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;
            }
    }
    

    很好懂,时间复杂度(O(N + M))
    但是,一旦利用桶的思想,就不可避免的遇到一个问题:空间
    比如我给你的数是这样的:

    1 12398517923876091 1000 1000000 10000000000 9999999 2345234618 1239 102358 12398517923876091 12398517923876091 12398517923876091 12398517923876091 12398517923876091 12398517923876091

    请问你要开多大的空间?12398517923876091个数组
    好,有的同学说可以离散化,我再给你一组数据:

    1 2 3 4 5 6 ... LONG_MAX 1 1 1 ...(LONG_MAX/2个1)

    从1到LONG_MAX全部给你,你怎么做?你继续离散化啊?你离散啊~你离散啊~你离散啊~
    (别问我为什么数据这么毒瘤,我自己出数据就是这么毒瘤)

    Part 2: 排序做法

    显然,若一个数列存在主元素,那么这个主元素在排序后一定位于(frac{n}{2})的位置
    那么我们又有想法了:

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

    看起来不错!(O(NlogN))的复杂度可还行?
    于是,一旦有(NlogN),就一定有人想出(N)。有吗?还真的有——

    Part 3:终极做法

    这个数列有个特性:由于主元素的出现的次数超过50%,那么在不断的消掉两个不同的元素之后,最后一定剩下主元素
    有的同学会问了:如果数列长度为偶数呢?
    我说这位同学,请 你 审 题

    给一个有(n)个元素的数列,保证有一个数(a)出现的次数超过50%,求这个数

    再读一次:

    保证有一个数(a)出现的次数超过50%

    还不懂?再读一次:

    超过50%

    再不懂?滚!
    输入时判断与上一次保存的输入是否相同,如不同则删除两数,这里用栈来实现。

    #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]);
    }
    
  • 相关阅读:
    [离散数学II]2017.5.9
    mysql内连接、左连接、右连接
    Android平台介绍
    软技能(面试)1
    流程控制练习题
    函数:算法
    linux系统文件
    App测试需注意
    python-循环
    python-正则表达式
  • 原文地址:https://www.cnblogs.com/sdltf/p/12389775.html
Copyright © 2020-2023  润新知