众数问题(递归、分治)

所谓众数,就是对于给定的含有N个元素的多重集合,每个元素在S中出现次数最多的成为该元素的重数,

多重集合S重的重数最大的元素成为众数。例如:S={1,2,2,2,3,5},则多重集S的众数是2,其重数为3。

现在你的任务是:对于给定的由m个自然数组成的多重集S,计算出S的众数及其重数。

解题思路:

(1)快速排序

(2)求中位数

(3)计算出中位数的最左端和最右端的位置,然后分割成2段数组

(4)中位数个数与左端个数比较,中<左 即最大众数可能存在左端,将左端再进行2段分割(递归)直到 中 > 左为止。 右端同理。。。

#include<bits/stdc++.h>

using namespace std;
const int maxn = 1e2+5;
int num , val,n;
int a[maxn];
void find(int &l,int &r,int id)
{
    l = id,r = id;
    while(a[l] == a[id] && l >= 1) --l;
    l++;
      while(a[r] == a[id] && r <= n) ++r;
    r--;
    return ;
}
void solve(int l,int r)
{
    if(l > r) return ;
    int mid = l + r >> 1;
    int i,j;
    find(i,j,mid);
    if(j - i + 1 > num)
    {
        num =  j - i + 1;
        val = a[mid];
    }
    if(i - l > num)
        solve(l,i-1);
    if(r - j > num)
        solve(j+1,r);
    return ;
}
int main()
{
    srand(0);
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    while(cin >> n)
    {
        /*for(int i = 1;i <= n;++i) cin >> a[i];*/
        for(int i = 1;i <= n;++i)
            a[i] = rand() % 10;         
        sort(a+1,a+n+1);
        for(int i = 1;i <= n;++i)
            printf("%d%c",a[i],i == n ? '\n' : ' '); 
        num = val = 0;
        solve(1,n);
        printf("%d %d\n",val,num);
     }
    return 0;
} 
    原文作者:递归与分治算法
    原文地址: https://blog.csdn.net/HowardEmily/article/details/78571604
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞