Maximum Gap
Given an unsorted array, find the maximum difference between the successive elements in its sorted form.
Try to solve it in linear time/space.
Return 0 if the array contains less than 2 elements.
You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
官方给出的Solution:
Suppose there are N elements and they range from A to B.
Then the maximum gap will be no smaller than ceiling[(B - A) / (N - 1)]
Let the length of a bucket to be len = ceiling[(B - A) / (N - 1)], then we will have at most num = (B - A) / len + 1 of bucket
for any number K in the array, we can easily find out which bucket it belongs by calculating loc = (K - A) / len and therefore maintain the maximum and minimum elements in each bucket.
Since the maximum difference between elements in the same buckets will be at most len - 1, so the final answer will not be taken from two elements in the same buckets.
For each non-empty buckets p, find the next non-empty buckets q, then q.min - p.max could be the potential answer to the question. Return the maximum of all those values.
大致意思就是:
找出数组中的最小值A和最大值B,若数组共有N个元素,则最大连续元素的差值不会小于ceiling[(B - A) / (N - 1)]。
用桶排序,每个桶的长度len = ceiling[(B - A) / (N - 1)],则桶的个数最多为 (B - A) / len + 1。
对于一个数组元素K,可以通过 (K - A) / len来得到它在哪个桶中,对于每个桶只需记录其中的最大值和最小值即可。
由于同一个桶中的元素最大差值是len - 1,所以最终的答案肯定是不同的桶的元素之差。
对于每一个非空的桶p,找到下一个非空的桶q,则q.min - p.max可能是答案,遍历每个桶最终的最大值即是答案。
1 public int maximumGap(int[] num) { 2 if(num == null || num.length < 2) { 3 return 0; 4 } 5 int len = num.length; 6 int max = num[0]; 7 int min = num[0]; 8 for(int i : num) { 9 max = Math.max(max, i); 10 min = Math.min(min, i); 11 } 12 // the maximum gap will be no smaller than ceiling[(max - min) / (len - 1)] 13 int gap = (int)Math.ceil((double)(max - min)/(double)(len - 1)); 14 //num of bucket 15 int bucketNum = (max - min) / gap + 1; 16 int[] bucketMin = new int[bucketNum]; 17 int[] bucketMax = new int[bucketNum]; 18 Arrays.fill(bucketMin, Integer.MAX_VALUE); 19 Arrays.fill(bucketMax, Integer.MIN_VALUE); 20 21 for(int i : num) { 22 //index of current element 23 int index = (i - min)/gap; 24 bucketMin[index] = Math.min(bucketMin[index], i); 25 bucketMax[index] = Math.max(bucketMax[index], i); 26 } 27 int ret = 0; 28 int preMax = min; 29 for(int i=0; i<bucketNum; i++) { 30 if(bucketMin[i] == Integer.MAX_VALUE && bucketMax[i] == Integer.MIN_VALUE) { 31 //empty bucket 32 continue; 33 } 34 ret = Math.max(ret, bucketMin[i] - preMax); 35 preMax = bucketMax[i]; 36 } 37 //last bucket 38 ret = Math.max(ret, max - preMax); 39 return ret; 40 }