最大间隙问题

最大间隙问题 

给定 n 个实数,求这n个实数在数轴上相邻2个数之间的最大差值,设计解最大间隙问题的线性时间算法

分析:输入n个实数时是无序的,但不能排序,一旦排序就不满足”线性时间算法”要求

最直接的方法:
接收n个输入的实数后,排序(从小到大或者从大到小都可以),再计算它们之间的间隙,找出最大的间隙。
但是这种排序不是线性时间算法。
可以用鸽笼原理(也叫做抽屉原理)解决

步骤:
1、接收输入的实数,找出最大值和最小值 

2、max和min可以通过遍历得知,把min到max之间的间隙等分,分成n-1个区间,每个区间都是大小相等的。
那么,min属于第一个区间,max属于最后一个区间。并且第i个区间的上限是第i+1个区间的下限。每个区间的大小为
gap=(max-min)/(n-1) 

3、把除去max和min的另外n-2个数放到n-1个区间里。numOfBucket是每个实数所属的区间号,count数组中对应的那个值加1,
证明该区间拥有至少一个实数。
把low[i]设置成max,把high[i]设置成min,是为了便于后面的判断 

4、最后判断最大的间隙时,如果一个区间内有两个或者以上的实数,那么它们之间的间隙肯定不是最大的,因为这些数都

挤到一块了。相反,跨区间的数才可能产生最大的间隙 


<span style="font-size:14px;">#include<stdio.h>
int main(){
	int n,i;
	scanf("%d",&n);//输入实数的个数
	float*number=new float[n];   
	//接收n个实数 
	for(i=0;i<n;i++){
		scanf("%f",&number[i]);
	}
	
	//找出其中的最大值和最小值
	float max,min;
	int maxIndex,minIndex;
	max=min=number[0];
	maxIndex=minIndex=0;
	for(i=0;i<n;i++){
		if(max<number[i]){
			max=number[i];
			maxIndex=i;
		}
		if(min>number[i]){
			min=number[i];
			minIndex=i;
		}
	} 
	
	//把除去max和min的另外n-2个数放到n-1个区间里
	int*count=new int[n-1];  
    float*high=new float[n-1];  
    float*low=new float[n-1];  
	float gap=(max-min)/(n-1);
	for(i=0;i<n-1;i++)  
    {  
        count[i]=0;  
        high[i]=min;  
        low[i]=max;  
    }  
	for(i=0;i<n-1;i++){
		int numOfBucket=(int)((number[i]-min)/gap);
		count[numOfBucket]++;
		if(number[i]<low[numOfBucket]){
			low[numOfBucket]=number[i];
		}
		if(number[i]>high[numOfBucket]){
			high[numOfBucket]=number[i];
		}
	}
	
	//第一个区间里面肯定有数,最起码min在里面 
 
    float temp=0;  
    float left=high[0]; //第一个桶里肯定有数  
    //输出最大的间距  
    for(i=1;i<n-1;i++)  
    {  
        if(count[i])  
        {   
            if(low[i]-left>temp)  
                temp=low[i]-left;  
            left=high[i];  
        }  
    } 
	printf("%.2f\n",temp);
	return 0;
} </span>
点赞