最大间隙问题

来源:互联网 发布:java报表技术 编辑:程序博客网 时间:2024/04/28 10:04
问题描述:                    
     给定n个实数x1,x2,...,xn,求这n个实数在实轴上相邻2个数之间的最大差值,要求设计线性的时间算法
解:
如果不考虑题目的限制条件,那么这道题目不难,很容易想到将这n个实数进行排序,然后遍历,那么所用时间为
Z = T(N) + G(N) 其中,T(N) 为对那个实数进行排序所需要的时间,G(N)为遍历n个实数的时间 。
目前我们所知道的最优的排序效率是 nlogn的。所以这条路走不通。

我的想法:将这n个实数都下取整,那么这n个实数都会落到实数轴上整数点上,有可能发生的情况是
 1.多个实数下取整后对应实数轴上的一个整数点,我们只保存这个点处的最大最小值,其他中间值不做记录。(最大间隙一定不会在这些数中)
 2.某些整数点处只有一个对应的下取整后的实数。
 3.某些整数点处没有对应的下取整后的实数。
                  (1)找到n个实数中的最小值和最大值,下取整,min max;
  (2)float low[max - min +1]  high[max - min +1] 若有多个实数对应,用于记录对应整数点处最小最大值;float buckets[max - min +1]用于记                         录只 有一个实数对应是的实际实数值。bool flag[max -min +1] 用于标记是只有一个对应还是多个,为之后遍历提供方便。
      vector<int> stable 用于记录出现过一个以上元素对应的桶序号。
  (3)遍历n个实数,将这些点下取整后放入这些桶中。
                  (4)这次是遍历有一个以上元素对应的桶,找到最大间隙。
例如如下9个实数:-4.1  -4.2   -2.3    0.5    1.2    2.3    2.7    5.6    5.9 

  
以上分析虽然可以做到时间复杂度线性增长,有一个问题就是空间复杂度可能很高,比如说一组实数的最大最小值之间相差很大很大的时候。

另外一种算法(王晓东书上讲过的):用鸽巢原理。
除了max 和 min 外的n-2个数被置于n-1个桶中,由鸽巢原理即知,至少有一个桶是空的,这意味着最大间隙不会出现在同一个同种的两个数之间,对每一个桶做一次线性扫描即可找到最大间隙。
原创粉丝点击