题目描述:给定n个实数,计算它们的最大间隙
输入
5
2.3 3.1 7.5 1.5 6.3
输出
3.2
算法思路:
抽屉原理: 把n个物品放到n-1个抽屉里,不管怎么分,则至少有一个桶有两个及以上的物品
- 分区间
先找到 最大值MAX 和 最小值MIN,然后 记录 len = (MAX-MIN) / (N-1) 这相当于我们分了(N-1)个区间,每个区间长度为 len - 放数字
将N个数字放入区间中,按 (int)( (array[i] - MIN)/len) 的规则来放入对应的区间 - 留大小
将每个区间中的最大值和最小值留下 - 求间隙
间隙存在与 某个区间的MAX 与 下一个间隙的MIN 之中
#include <stdio.h>
#define INF 0x3f3f3f3f3f
#define N 5
double array[N] = {2.3, 3.1, 7.5, 1.5, 6.3};
/*
鸽笼原理(抽屉原理):把n个物品放到n-1个抽屉里,不管怎么分,则至少有一个桶有两个及以上的物品
算法思路
1.分区间
先找到 最大值MAX 和 最小值MIN,然后 记录 len = (MAX-MIN) / (N-1) , 这相当于我们分了(N-1)个区间,每个区间长度为 len
2.放数字
将N个数字放入区间中,按 (int)( (array[i] - MIN)/len) 的规则来放入对应的区间
3.留大小
将每个区间中的最大值和最小值留下
4.求间隙
间隙存在与 某个区间的MAX 与 下一个间隙的MIN 之中
*/
int main(){
//初始化区间
int count[N] = {0};
double maxn[N - 1], minn[N - 1];
int i;
for(int i = 0; i < N - 1; i ++){
maxn[i] = -INF;
minn[i] = INF;
}
//找出区间长度
double maxNum = array[0], minNum = array[0];
for(int i = 1; i < N; i ++){
if(array[i] > maxNum)
maxNum = array[i];
if(array[i] < minNum)
minNum = array[i];
}
double len = (maxNum - minNum) / (N - 1);
int index;
for(i = 0; i < N; i ++){
index = (int) ((array[i] - minNum) / len);
if(maxn[index] < array[i])
maxn[index] = array[i];
if(minn[index] > array[i])
minn[index] = array[i];
count[index] ++;
}
//计算最大间隔
int lastIndex, nowIndex;
double gap = 0, lastGap, nowGap;
for(i = 0; i < N - 1;){
lastIndex = i;
lastGap = maxn[i];
while(count[i + 1] == 0){
i ++;
}
nowIndex = i + 1;
nowGap = minn[nowIndex];
if(nowGap - lastGap > gap)
gap = nowGap - lastGap;
i = nowIndex;
}
printf("%f\n", gap);
return 0;
}
参考文章:理解最大间隙问题算法