zoukankan      html  css  js  c++  java
  • 15 最大间隙问题

    问题描述:
    最大间隙问题:给定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));
    }

    }

  • 相关阅读:
    P1939 矩阵加速(数列)
    P3390 矩阵快速幂
    快速幂
    1236:区间合并
    1183:病人排队
    1230:寻找平面上的极大点
    1244:和为给定数
    1228 书架
    1222 放苹果
    洛谷5015标题统计
  • 原文地址:https://www.cnblogs.com/taotao315/p/2952040.html
Copyright © 2011-2022 走看看