/* * 164. Maximum Gap * 2016-6-4 by Mingyang * 这个题目首先要求的是linear的时间,所以我个人的预测就是bucketsort * bucketsort就是把一个list分成几个bucket再分别把每一个桶排序,再合起来 * 比如我现在有10个如果selection sort就是100的时间复杂度,那么需要分成两个5 * 就是两个25相加,就是50 * 假设有N个元素A到B。 * 那么最大差值不会小于ceiling[(B - A) / (N - 1)] * 令bucket(桶)的大小len = ceiling[(B - A) / (N - 1)],则最多会有(B - A) / len + 1个桶 * 对于数组中的任意整数K,很容易通过算式loc = (K - A) / len找出其桶的位置,然后维护每一个桶的最大值和最小值 * 由于同一个桶内的元素之间的差值至多为len - 1,因此最终答案不会从同一个桶中选择。 * 对于每一个非空的桶p,找出下一个非空的桶q,则q.min - p.max可能就是备选答案。返回所有这些可能值中的最大值。 */ public int maximumGap(int[] num) { if (num == null || num.length < 2) return 0; // get the max and min value of the array int min = num[0]; int max = num[0]; for (int i:num) { min = Math.min(min, i); max = Math.max(max, i); } // the minimum possibale gap, ceiling of the integer division int gap = (int)Math.ceil((double)(max - min)/(num.length - 1)); int[] bucketsMIN = new int[num.length - 1]; // store the min value in that bucket int[] bucketsMAX = new int[num.length - 1]; // store the max value in that bucket Arrays.fill(bucketsMIN, Integer.MAX_VALUE); Arrays.fill(bucketsMAX, Integer.MIN_VALUE); // put numbers into buckets for (int i:num) { if (i == min || i == max) continue; int idx = (i - min) / gap; // index of the right position in the buckets bucketsMIN[idx] = Math.min(i, bucketsMIN[idx]); bucketsMAX[idx] = Math.max(i, bucketsMAX[idx]); } // scan the buckets for the max gap int maxGap = Integer.MIN_VALUE; int previous = min; for (int i = 0; i < num.length - 1; i++) { if (bucketsMIN[i] == Integer.MAX_VALUE && bucketsMAX[i] == Integer.MIN_VALUE) // empty bucket continue; // min value minus the previous value is the current gap maxGap = Math.max(maxGap, bucketsMIN[i] - previous); // update previous bucket value previous = bucketsMAX[i]; } maxGap = Math.max(maxGap, max - previous); // updata the final max value gap return maxGap; }