最大间距问题
给定n个实数x1,x2,…xn,求这n个数在实轴上相邻两个数之间的最大差值,要求设计线性的时间算法。
最容易想到的是先对n个数据进行排序,然后一边扫描即可确定相邻的最大间隙。但该方法不能满足线性时间的要求。故采取如下方法:
1. 找到n个数据中最大和最小数据maxnum和minnum;
2. 用n—2个点等分区间[minnum, maxnum],即将[minnum, maxnum]等分为n-1个区间(前闭后开区间),将这些区间看做桶,编号为1,2,…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. 求最大间隙:
除最大最小数据maxnum和minnum以外的n-2个数据被放入n-1个桶中,由抽屉原理可知至少有一个桶是空的;又因每个桶的大小相同,所以最大间隙不会在同一桶中出现;
一定是某个桶的上界(dblHigh)和其后某个桶的下界(dblLow)之间隙,且该两桶之间的桶(即编号在该两桶编号之间的桶)一定是空桶;即最大间隙在桶i的上界和桶j的下界之间产生(j>=i+1);
#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"); }