有一道题大概是这样的:有n条水平的线,知道线的纵坐标,选择一条线,使得这条线到所有线的距离之和最小。
根据数学知识,我们知道,如果线是奇数条的话,那么中间那条(纵坐标的中位数)即可,如果是偶数条的话,那么中间那2条区间内的都可以,而如果要线的纵坐标尽可能小,那么就取中间两条纵坐标较小的那条即可。
那么在线数量为偶数的时候,这并不是传统的求中位数问题,而线数量为奇数的时候,则变成传统的中位数问题。
求中位数的方法可以先排序然后直接取中间的一条即可,但是对于大数据量来说,排序不可行。利用线性时间选择可以再O(n)下找到中位数。
线性时间选择将数组分成3部分,一部分是基准(1个数),其他两部分是大于这个基准的数组和小于基准的这个数组,对于长度为n的数组来说,我们目的是找到第k=(1+n)/2个数,那么就可以根据k和基准的关系来判断第二次是在小于基准的数组里查找还是在大于基准里的数组查找。程序如下:
#include<iostream>
using namespace std;
#define MAX 100001
int main()
{
int a[MAX];
int *p=a;
int x,y,t1,n=0;
char t2;
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
int* small=new int[n]; //小于中位数的集合
int* big=new int[n]; //大于中位数的集合
int equal; //等于中位数的那个数,也就是基准
int k=(1+n)/2; //处于数组最中间索引的元素
while(1)
{
int x=p[rand()%n]; //随机选取一个数做基准
int n_s=0,n_b=0;
for(int i=0;i<n;i++) //将n个数划分成3组:小的集合,基准,大的集合
{
if(p[i]>x) big[n_b++]=p[i];
else if(p[i]==x) equal=x;
else small[n_s+

该博客探讨了一种在无序数组中寻找中位数的方法,特别是针对大数据量的情况,避免了排序操作。当线的数量为奇数时,问题转化为传统的中位数问题;偶数时则需要特定策略。通过线性时间选择算法,可以在O(n)的时间复杂度内找到中位数。博主提供了具体的程序实现,利用分治策略确定基准并迭代搜索目标位置。
最低0.47元/天 解锁文章
1126

被折叠的 条评论
为什么被折叠?



