给定一个无序数组,求这组数在排序后相邻数间差的最大值

题目来源:https://oj.leetcode.com/problems/maximum-gap/

题目大意:RT

这个题最差的方式是排序,当然时间复杂度是nlogn。

是否有n的方法呢?

假设这组数的最大值为max,最小值为min,对于这样的数据,最差情况就是所有的值的差都相同,那么相邻的最大值为(max-min)/(n-1)。而且修改任何一个数字都将造成结果的增加。

通过这种方法,把min~max分割成N-1个区间(前闭后开),然后将每个数放到对应的区间里。
这样,相邻数字差的最大值其实和区间内的数据无关了(因为区间内无论计算,其结果都将<(max-min)/(n-1))。这样分组后,最终的结果应当就是前一个区间的最大值与后一个区间的最小值的差,当然会出现空的区间,做个标记即可。

时间和空间复杂度都为O(N)

/**
 * Created by jpbirdy on 15-1-16.
 */

package jpbirdy.leetcode;

/**
 * 给定一个无序数组,找到数组中排序后相邻差最大的值
 *
 * @author jialou.jp
 * @project JavaAlgorithms
 * @class MaxGap
 * @date 15-1-16 17:01
 */
public class MaxGap
{
    public int maximumGap(int[] num)
    {
        int maxGap = 0;

        // edge case
        if (num.length < 2)
        {
            return maxGap;
        }

        // get maximum and minimum
        int min = num[0];
        int max = num[0];
        for (int i = 0; i < num.length; i++)
        {
            if (num[i] < min)
                min = num[i];
            if (num[i] > max)
                max = num[i];
        }

        // divide into identical gaps
        Gap[] gaps = new Gap[num.length - 1];
        boolean[] Engaged = new boolean[num.length - 1];
        double gap = (double) (max - min) / (double) (num.length - 1);
        for (int i = 0; i < gaps.length; i++)
            Engaged[Math.min((int) Math.floor((double) (num[i] - min) / gap), gaps.length - 1)] = true;

        // assign maximum and minimum for each gap
        for (int i = 0; i < gaps.length; i++)
            gaps[i] = new Gap();
        for (int i = 0; i < num.length; i++)
        {
            int index = (int) Math.floor((double) (num[i] - min) / gap);
            index = Math.min(index, gaps.length - 1);

            // lower bound
            if (gaps[index].low == -1)
                gaps[index].low = num[i];
            else
                gaps[index].low = Math.min(gaps[index].low, num[i]);

            // upper bound
            if (gaps[index].high == -1)
                gaps[index].high = num[i];
            else
                gaps[index].high = Math.max(gaps[index].high, num[i]);
        }

        // find maximum gap
        for (int i = 0; i < gaps.length; i++)
        {
            if (Engaged[i])
            {
                // check its inner gap
                maxGap = Math.max(gaps[i].high - gaps[i].low, maxGap);

                // lower all the way
                int j = i;
                while (--j >= 0)
                {
                    if (Engaged[j])
                        break;
                }
                if (j >= 0)
                    maxGap = Math.max(gaps[i].low - gaps[j].high, maxGap);

                // upper all the way
                j = i;
                while (++j < num.length - 2)
                {
                    if (Engaged[j])
                        break;
                }
                if (j < gaps.length)
                    maxGap = Math.max(gaps[j].low - gaps[i].high, maxGap);
            }
        }

        return maxGap;
    }

    class Gap
    {
        int low;
        int high;
        boolean hasItem;

        Gap()
        {
            low = -1;
            high = -1;
        }

        Gap(int x, int y)
        {
            low = x;
            high = y;
        }
    }

    public static void main(String[] args)
    {
        int[] num = {1, 2, 3, 5, 7, 9};
        System.out.println((new MaxGap()).maximumGap(num));
    }

}


你可能感兴趣的:(算法)