[Leetcode] 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:
http://cgm.cs.mcgill.ca/~godfried/teaching/dm-reading-assignments/Maximum-Gap-Problem.pdf
由于要求时间和空间复杂度是O(n), 因此用Java自带的sort就不行了(因为STL函数的sort()的复杂度是O(nlogn))
所以我们在思考得用一种线性的排序方法来做此题,那么,线性的排序算法有哪些呢?
Answer: 计数排序,基数排序,桶排序。
下面的code是利用桶排序来做的。
假设有N个元素A到B。
那么最大差值不会小于ceiling[(B - A) / (N - 1)],令bucket的大小len = ceiling[(B - A) / (N - 1)],初始化N-1个桶。
对于数组中的任意整数K(只针对数组中非min,max的值来放入桶中),很容易通过算式loc = (K - A) / len找出其桶的位置,然后维护每一个桶的最大值和最小值
由于同一个桶内的元素之间的差值至多为len - 1,因此最终答案不会从同一个桶中选择。
对于每一个非空的桶p,找出下一个非空的桶q,则q.min - p.max可能就是备选答案。返回所有这些可能值中的最大值。
public class Solution { public int maximumGap(int[] num) { if(num==null||num.length<2) return 0; if(num.length==2) return num[0]>num[1]?num[0]-num[1]:num[1]-num[0]; int min=Integer.MAX_VALUE; int max=Integer.MIN_VALUE; for(int i:num){ min=Math.min(min, i); max=Math.max(max, i); } int gapRange=(int) Math.ceil((double)(max-min)/(num.length-1)); int[] bucketsMIN=new int[num.length-1]; int[] bucketsMAX=new int[num.length-1]; Arrays.fill(bucketsMIN, Integer.MAX_VALUE); Arrays.fill(bucketsMAX, Integer.MIN_VALUE); for(int i:num){ if(i==min||i==max) continue; int idx=(i-min)/gapRange; bucketsMIN[idx]=Math.min(bucketsMIN[idx], i); bucketsMAX[idx]=Math.max(bucketsMAX[idx], i); } int previous=min; int maxGap=Integer.MIN_VALUE; for(int i=0;i<num.length-1;++i){ if(bucketsMAX[i]==Integer.MIN_VALUE&&bucketsMIN[i]==Integer.MAX_VALUE)
//说明桶是空的 continue; maxGap=Math.max(maxGap, bucketsMIN[i]-previous); previous=bucketsMAX[i]; } maxGap=Math.max(maxGap, max-previous); return maxGap; } }