问题描述:给定n个实数x1,x2,...,xn,求这n(n>=2)个实数在实轴上相邻2个数之间的最大差值,要求设计线性的时间算法
#include <stdio.h>
#include <stdlib.h>
void MaxGap(int n,double *num){
int i,index;
double *low = (double *)malloc(sizeof(double)*n); //每个鸽舍的最小数据
double *high = (double *)malloc(sizeof(double)*n); //每个鸽舍的最大数据
int *flag = (int *)malloc(sizeof(int)*n); //标记鸽舍是否为空
double avr_gap,minx,maxx,max_gap;
//确定间距
minx = maxx = num[0];
for(i=1;i<n;i++){
if(num[i] < minx)
minx = num[i];
if(num[i] > maxx)
maxx = num[i];
}
avr_gap = (maxx - minx)/(n-1);
if(minx == maxx)
printf("0\n");
else if(n == 2){
printf("%lf\n",maxx - minx);
}
else{
//入鸽,只确定最大和最小值
//memset(flag,0,sizeof(flag));//用memset对malloc开辟的数组 初始化只能修改flag[0]的值
for(i=0;i<n;i++){//注意:首先初始化
low[i] = maxx;
high[i] = minx;
flag[i] = 0;
}
//将除minx和maxx之外的(n-2)个数放在(n-1)个鸽舍中,
//由抽屉原理可知至少有一个鸽舍是空的,又因为每个鸽舍大小相同,所以最大间隙不会在同一个鸽舍中出现,
//一定是某个鸽舍的上界和其后某个鸽舍的下界之差
//而将minx和maxx放入鸽舍(0鸽舍和(n-1)鸽舍)仍然有这个结论
for(i=0;i<n;i++){
index = (int)((num[i]-minx)/avr_gap);//鸽舍左闭右开(除最后一个鸽舍)
if(!flag[index])
flag[index] = 1;
if(low[index] > num[i])
low[index] = num[i];
if(high[index] < num[i])
high[index] = num[i];
}
//MaxGap = max(Minj-Maxi)
for(i=1;i<n;i++)
if(flag[i])
break;
max_gap = low[i] - high[0];
index = i;
for(++i;i<n;i++){
if(flag[i]){
if(low[i] - high[index] > max_gap)
max_gap = low[i] - high[index];
index = i;
}
}
printf("%lf\n",max_gap);
}
}
int main(){
int n,i;
double *num;
printf("n:");
scanf("%d",&n);
num = (double *)malloc(sizeof(double)*n);
for(i=0;i<n;i++)
scanf("%lf",&num[i]);
//用鸽舍法求最大间隙问题(用n-2个等间距点分割区间[minx,maxx],产生n-1个段)
MaxGap(n,num);
return 0;
}
样例:
5
2.3 3.1 7.5 1.5 6.3---->3.2
5
2.3 3.1 10.0 1.5 6.3---->3.7
10
2.5 7.2 6.3 4.9 10.6 5.3 4.8 3.0 10.5 5.7
排序:2.5 3.0 4.8 4.9 5.3 5.7 6.3 7.2 10.5 10.6 3.3----->3.3