最大间距问题

给定n个实数x1x2…xn,求这n个数在实轴上相邻两个数之间的最大差值,要求设计线性的时间算法。

 

最容易想到的是先对n个数据进行排序,然后一边扫描即可确定相邻的最大间隙。但该方法不能满足线性时间的要求。故采取如下方法:

1.       找到n个数据中最大和最小数据maxnumminnum

2.       n—2个点等分区间[minnum, maxnum],即将[minnum, maxnum]等分为n-1个区间(前闭后开区间),将这些区间看做桶,编号为12…n-1,且桶i的上界和桶i+ 1的下界相同,即每个桶的大小相同;

每个桶的大小: space = (maxnum - minnum) / (n - 1),且人为地将minnum放入第1个桶,将maxnum放入第n-1个桶;

3.     编程实现中,用以下数据结果存放有关桶的数据:

 int *count=new int[n];  //实际分到每个桶的数据个数

double *low=new double[n]; //实际分到每个桶的最小数据

double *high=new double[n]; //实际分到每个桶的最大数据

4.    n个数放入n-1个桶中:

 按如下规则将x[i]分配到某个桶(编号index)中:  index=int((data[i]-minnum)/space)+1

x[i]=minnum,则被分到第1个桶中(minnum即为桶1的下界)

x[i]=j的下界(也是桶j-1的上界),则被分到桶j(j>=1)

x[i]=maxnum,则被分到桶n(max为桶n的下界桶n-1的上界),但没有桶n,解决办法:

可人为将其移入桶n-1中或者再加一个桶,这并不影响求其最大间隙;

调整分到该桶的最大最小数据;

 count[location]++;  //有数据存入,计数值加1 
         if(data[i]<low[location]) //如果数据比左端值小,则作为左端值 

             low[location]=data[i];
         if(data[i]>high[location]) //如果数据比右端值大,则作为右端值 

             high[location]=data[i];

5.    求最大间隙:

除最大最小数据maxnumminnum以外的n-2个数据被放入n-1个桶中,由抽屉原理可知至少有一个桶是空的;又因每个桶的大小相同,所以最大间隙不会在同一桶中出现;

一定是某个桶的上界(dblHigh)和其后某个桶的下界(dblLow)之间隙,且该两桶之间的桶(即编号在该两桶编号之间的桶)一定是空桶;即最大间隙在桶i的上界和桶j的下界之间产生(j>=i+1)

View Code
#include<iostream>
using namespace std;

double findmin(double data[], int n)
{
    int index;
    double minnum = data[0];
    for(int i = 1; i < n; i ++){
        if(data[i] < minnum){
            minnum = data[i];
            index = i;    
        }    
    }
    return minnum;    
}

double findmax(double data[], int n)
{
    int index;
    double maxnum = data[0];
    for(int i = 1; i < n; i ++){
        if(data[i] > maxnum){
            maxnum = data[i];
            index = i;    
        }    
    }    
    return maxnum;
}

void init(int count[], double low[], double high[], int n, double minnum, double maxnum)
{
    for(int i = 1; i < n; i ++){
        count[i] = 0;
        low[i] = maxnum;
        high[i] = minnum;    
    }    
}

void datain(double space, int count[], double low[], double high[], int n, double data[], double minnum)
{
    for(int i = 1; i < n; i ++){
        int location = (int)((data[i] - minnum) / space) + 1;    
        if(location == n){
            location --;    
        }
        count[location] ++;
        if(data[i] < low[location]){
            low[location] = data[i];    
        }
        if(data[i] > high[location]){
            high[location] = data[i];    
        }
    }    
}

double findMaxGap(int n, double low[], double high[], int count[])
{
    double maxgap = 0;
    double dhigh = high[1];
    for(int i = 2; i < n; i ++){
        if(count[i]){
            double tmp = low[i] - dhigh;
            if(tmp > maxgap){
                maxgap = tmp;    
            }    
            dhigh = high[i];
        }    
    }
    return maxgap;
}

int main()
{
    const int n = 10;
    double data[n] = {1.0, 2.0,3.0,5.0,6.0,7.0,10.0, 20.0, 22.0, 100.0};
    double minnum, maxnum;
    double space, maxgap;
    double low[n], high[n];
    int count[n];
    minnum = findmin(data, n);
    maxnum = findmax(data, n);
    space = (maxnum - minnum) / (n - 1);
    init(count, low, high, n, minnum, maxnum);
    datain(space, count, low, high, n, data, minnum);
    cout << findMaxGap(n, low, high, count) << endl;
    system("pause");
}

 

posted @ 2012-04-19 21:45  爱也玲珑  阅读(332)  评论(0编辑  收藏  举报