最大间隙问题

 

问题描述:

  最大间隙问题:给定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

算法思想分析: 

  对于给定的n 个实数先取得其最大值和最小值,n个数的大小范围为[min,max];剩余n-2个点等分区间[min,max]产生n-1个闭区间的桶,如果我们假设每个桶的区间为[,)所以要增加一个桶放max共n个桶。max放入最后一个桶中,所以除max外的n-1个数置于n-1个桶中,由于min固定被放入第一桶里,剩下的n-2个数据,如果还存在数据放入第一桶则势必存在至少有一个桶为空,则意味着最大间隙不会出现在同一个桶中的两个数之间。如果剩下的数据不放人第一桶,则n-2数据放入n-2个桶中,如果同一个桶中有两个数,则必然出现有一个桶为空。所以最大间隙不会出现在同一个桶中,所以只需要记录桶中的最大值和最小值。所以最大值为对每个桶做一次线性扫描,比较 过滤掉空桶的所有桶中相邻两桶取(后面桶的最小值 - 前面桶的最大值)的最大值。

 

 //求数组中最小数据下标和最大数据下标
        static void GetIndex(double[] array,out int indexMin,out int indexMax)
        {
            indexMin = 0;
            indexMax = 0;
            double tempMin = array[0];
            double tempMax = array[0];
            for (int i = 1; i < array.Length; i++)
            {
                if (array[i] < tempMin)
                {
                    tempMin = array[i];
                    indexMin = i;
                }
                if (array[i] > tempMax)
                {
                    tempMax = array[i];
                    indexMax = i;
                }
            }

        }

 

定义数据结构

View Code
public struct Gap
    {
        //实际分配到该桶的数据个数
        public int Count
        {
            get;
            set;
        }

        //记录分配到该桶的最小数据
        public double Low
        {
            get;
            set;
        }
        //记录分配到该桶的最大数据
        public double High
        {
            get;
            set;
        }
    }

 

获取最大间隙值

        static  double GetMaxGap(double[] array)
        {
            int indexMin;
            int indexMax;
            GetIndex(array, out indexMin, out indexMax);
            double min = array[indexMin];
            double max = array[indexMax];
            //用length-2个点等分区间[min,max]产生length-1个桶,每个桶的区间为[,)所以要增加一个最后一个桶放max
            Gap[] gaps = new Gap[array.Length];
            
            //构造桶时,Low赋最大值,High赋最小值
            for (int i = 0; i < gaps.Length; i++)
            {
                gaps[i].Count = 0;
                gaps[i].Low = max;
                gaps[i].High = min;
            }

            //由于min放入第一个桶,max放入最后一个桶中,所以除max外的length-1个数置于length-1个桶中,
            //由于min固定被放入第一桶里,剩下的length-2个数据,如果还存在数据放入第一桶则势必存在至少有一个桶为空,则意味着最大间隙不会出现在同一个桶中的两个数之间
            //如果剩下的数据不放人第一桶,则length-2数据放入length-2个桶中,如果同一个桶中有两个数,则必然出现有一个桶为空
            //所以最大间隙不会出现在同一个桶中,所以只需要记录桶中的最大值和最小值

           //初始化桶中最小值、最大值
            for (int i = 0; i < array.Length; i++)
            {
                int bucket = (int)((array.Length - 1)*(array[i] - min) / (max - min));
                gaps[bucket].Count++;
                if (array[i] < gaps[bucket].Low) gaps[bucket].Low = array[i];   //记录桶里的最小值
                if (array[i] > gaps[bucket].High) gaps[bucket].High = array[i]; //记录桶里的最大值
            }

            double maxGap = 0;
            double left = gaps[0].High; //初始值为第一个桶中的最大值 如果第一个桶为空则为min值


            //对每个桶做一次线性扫描,比较 过滤掉空桶的所有桶中相邻两桶取(后面桶的最小值 - 前面桶的最大值)的最大值
            for (int i = 0; i < gaps.Length; i++)
            {
                //如果桶中有值
                if (gaps[i].Count != 0)
                {
                    double tempGap = gaps[i].Low - left;
                    if (tempGap > maxGap) maxGap = tempGap;
                    left = gaps[i].High;
                }

            }

            return maxGap;
        }

 

总结:以上纯属个人的理解,对于有些地方觉得还是理解不是很深,有不足之处和错误的地方希望大家帮我指出。谢谢

 

 

 

转载于:https://www.cnblogs.com/gyb333/archive/2012/12/20/MaxGap_Problem.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值