1-5 最大间隙问题

问题描述:
最大间隙问题:给定n 个实数x1 , x2 , , xn ,求这n 个数在实轴上相邻2 个数之间的最大差值。假设对
任何实数的下取整函数耗时O(1),设计解最大间隙问题的线性时间算法。
编程任务:
对于给定的n 个实数 x1 , x2, ……, xn,编程计算它们的最大间隙。
数据样例:
输入数据:
5
2.3 3.1 7.5 1.5 6.3
输出数据:
3.2
解题思路:
1,比较直接的方法是先对n个数进行排序,最快时间为nlogn,然后遍历数据顺便计算每两个数据之间的间隔
该方法不是线性时间
2,想要用线性时间解决该问题可以使用组合数学中学到的鸽巢原理,将n个数放入n-1个桶中,每个桶大小相同为(max-min)/(n-1)且有一个上界和一个下界,第i个桶的上界为第i+1个桶的下界;
由于除去最小数字和最大数字还剩下n-2个数字,因此至少有一个桶是空的,因为最小数字一定是第1个桶的下界,最大数字一定是第n-1个桶的上界;
初始状态每个桶的上下界分别为[max,min],遍历所有数字(O(n)时间),将每个数字放入到第对应的桶中,并更新桶的上下界,例如有一个4-6的桶初始界为[8,2],只有5落入该桶,则桶的上下界更新为[5,5],并设置计数器count记录每个桶中的数字个数;
然后,一次线性扫描即可得到最大间隙。
 
源代码如下:

#include <stdio.h>
#include <stdlib.h>

int mini(int n, double *num)
{
double min = 0.0;
int k,i;
for (i = 0, k = 1; i < n; i++) {
if (num[i] < min) {
min = num[i];
k = i;
}
}
return k;
}

int maxi(int n, double *num)
{
double max = 0.0;
int k, i;
for (i = 0, k = 1; i < n; i++) {
if (num[i] > max) {
max = num[i];
k = i;
}
}
return k;
}

double maxgap(int n, double *num)
{
double minx = num[mini(n, num)];
double maxx = num[maxi(n, num)];

double avg = (maxx - minx) / (n-1);

int *count = malloc((n+1)*sizeof(int));
double *low = malloc((n+1)*sizeof(double));
double *high = malloc((n+1)*sizeof(double));

int i;
for (i = 0; i < n; i++) {
count[i] = 0;
low[i] = maxx;
high[i] = minx;
}

for (i = 0; i < n; i++) {
int bucket = (int)((num[i] - minx)/avg);
count[bucket]++;
if (num[i] < low[bucket]) {
low[bucket] = num[i];
}
if (num[i] > high[bucket]) {
high[bucket] = num[i];
}
}
double tmp = 0, left = high[0];

for (i = 1; i < n-1; i ++) {
if (count[i]) {
double thisgap = low[i] - left;
if (thisgap > tmp) {
tmp = thisgap;
}
left = high[i];
}
}
return tmp;

}

int main()
{
int n, i;
double num[100];
while(scanf("%d", &n) != EOF) {
for (i = 0; i < n; i++) {
scanf("%lf", &num[i]);
}
printf("%.4f\n", maxgap(n, num));
}

}

posted on 2013-03-09 22:01  愤怒的屎壳螂  阅读(981)  评论(0编辑  收藏  举报

导航