分治算法解决众数问题

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


分析:

  • 先用快速排序给数组从小到大排好序,接着找出中位数,(元素个数除2就是它的位置),以中位数为参考点,找出中位数的最左最右边界,例如上面的就是1和3,再以2个边界把数组分成2半,中位数个数与左端个数(数组最低位置到中位数的左边界)比较,中<左 即最大众数可能存在左端,将左端再进行2段分割(递归)直到 中 > 左为止。 右端同理。。。
  • 代码如下:
#include<bits/stdc++.h>
using namespace std;
#define M 100
int a[M];
int num,val,n; //重数, 众数,个数 

void find(int &l,int &r,int mid)//找中位数的最左,最右边界位置 
{
l = r= mid;
 while(a[l]==a[mid] && l>= 0) --l;
 l++; //还原 
 while(a[r]==a[mid] && r<= n-1) ++r;
 r--; 
}
void Fun(int low,int high)
{
 if(low > high) return; //左右边界交叉,结束 
 int mid = (low + high)/2; //中位数
 int i,j;
 find(i,j,mid);
 if(j-i+1 > num){ //更新 
  num = j-i+1;
  val = a[mid];
 } 
 if(i-low > num){//分治递归 
  Fun(low,i-1);
 }
 if(high -j > num){
  Fun(j+1,high);
 }
}
main()
{
 int  i;
 cout<<"输入元素个数:\n"; 
 cin>>n;
 cout<<"输入元素:\n";
 for(i=0;i<n;i++)
  cin>>a[i];
 sort(a,a+n);
 for(i=0;i<n;i++)
  cout<<a[i]<<",";
 Fun(0,n-1); 
 cout<<endl<<"众数:"<<val<<" 重数:"<<num; 
 return 0;
}

-运行结果:

输入元素个数:
6
输入元素:
1 2 2 5 3 2
1,2,2,2,3,5,
众数:2 重数:3
--------------------------------
Process exited after 11.13 seconds with return value 0
请按任意键继续. . .
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值