分治法求众数

   日期:2020-11-10     浏览:98    评论:0    
核心提示:分治法求众数Problem Description给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。例如,S={1,2,2,2,3,5}。多重集S的众数是2,其重数为3。求众数方法很多,现要求你用分治算法来试一试,并分析其效率。编程任务:对于给定的由n个自然数组成的多重集S,采用分治算法编程计算S的众数及其重数。Input第1行多重集S中元素个数n;接下来的一行为集合S,有n个自然数。( n < 1000000 )Out

分治法求众数


Problem Description

给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为
众数。例如,S={1,2,2,2,3,5}。多重集S的众数是2,其重数为3。

求众数方法很多,现要求你用分治算法来试一试,并分析其效率。

编程任务:对于给定的由n个自然数组成的多重集S,采用分治算法编程计算S的众数及其重数。


Input

第1行多重集S中元素个数n;接下来的一行为集合S,有n个自然数。( n < 1000000 )


Output

结果输出:输出2个数,第1个数为众数,第2个为其重数。
当有多个同样重数的众数,优先输出数值更小的数的众数。


Sample Input

6 
1 2 2 2 3 5

Sample Output

2 3

Hint

提示陆续写上来,不着急,先自行思考和讨论……


Solution

题目说要用分治的解法,不过如果想过这题,一个for循环也是暴力统计求解。

但既然是要学算法,那我们当然要用分治的思想啦!


分治策略

1.我们首先假设中间的元素是众数
2. 然后由两边向中间遍历,直到左右都出现值等于众数的数,记录下众数和重数
3. 这样就将一个数组分为三部分,我们再对左右部分执行上述步骤
4. 注意:使用分治策略解决众数问题需要原集合有序,在原集合无序的情况下需要对其排序建议数据输入之后先进行排序


当真正理解了分治的思想,这题就迎刃而解啦。这题的分治体现在将数组分为三部分进行众数的统计,可以参考下图理解。



Code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>



using namespace std;
typedef long long ll;
typedef pair<int,int>pi;

const int maxn=1e5+100;
const int N=1e6+100;
const int M=1e5+100;
const int mod=1e9+7;

int n,m,T;
int a[N];
int ans=0; //众数的重数
int idx=0; //众数的下标


void split(int l,int r) //分治算法
{ 
    if(l>r)return;

    int ll=l; //记录原来的l位置
    int rr=r; //记录原来的r位置

    int mid=(l+r)>>1;

    for(; l<mid&&a[l]!=a[mid]; l++); //寻找众数的最左边

    for(; r>mid&&a[r]!=a[mid]; r--); //寻找众数的最右边
    
    //经过两个for循环后,众数个数就是r-l+1

    if(ans<=r-l+1) //更新答案
    { 
        if(ans==r-l+1)
        { 
            idx=min(mid,idx);
        }
        else
            idx=mid;
        ans=r-l+1;
    }

    if(l-1-ll+1>=ans) //剪枝
        split(ll,l-1); // 对左边部分分治

    if(rr-r-1+1>=ans) //剪枝
        split(r+1,rr); // 对右边部分分治

}



void solve()
{ 
    scanf("%d",&n);
    for(int i=0; i<n; i++)
        scanf("%d",a+i);

    sort(a,a+n); //先排序,方便统计众数个数

    int l=0;
    int r=n-1;

    split(l,r);

    printf("%d %d\n",a[idx],ans);

}


int main()
{ 
#ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif
    solve();

    
}




最后感谢小伙伴们的学习噢~

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服