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.
写这道题前,先了解一下时间复杂度为线性的几种排序方法:
计数排序:http://www.cnblogs.com/archimedes/p/counting-sort-algorithm.html
注意k值不是长度,而是待排序数组中的最大值。
基数排序:http://www.cnblogs.com/archimedes/p/4017789.html
桶排序:http://www.cnblogs.com/archimedes/p/bucket-sort-algorithm.html
这道题用桶排序来做,同一个桶里的数差值不会有不同桶间的差值大,所以找桶内最大和下一个非空桶的桶内最小进行比较即可。
注意桶的个数和len的计算方法,算错答案会不对(多桶或少桶最后计算的差值肯定不对,多的话可能会取到不必要的初始值MAX_VALUE)。应该是num.length + 1个桶。
为什么最大差值一定在桶间而非桶内?假如目前有5个桶,num = {1,2,3,100},那1,2,3肯定在0号桶,100在4号桶,这种情况一定是桶间距离最大。由于桶的个数是num.length + 1,极端状态是每个桶里都有值,那最大差值也是在桶间,即桶间差值都相同。
Source
public int maximumGap(int[] num) {
if(num.length < 2) return 0;
int max = Integer.MIN_VALUE, min = Integer.MAX_VALUE;
for(int i = 0; i < num.length; i ++){
if(num[i] > max) max = num[i];
if(num[i] < min) min = num[i];
}
int len = (int) Math.ceil((double)(max - min) / (num.length - 1)); //桶内数的最大差 向上取整 注意里面一定要先换算成double 要不就先向下取整了(int型除法)
if(num.length == 2) return max - min;
int n = (max - min) / len;
int[] bMin = new int[n + 1]; //n + 1 个 *** 其实应该可以用num.length + 1
int[] bMax = new int[n + 1];
Arrays.fill(bMin, Integer.MAX_VALUE); //Arrays.fill相当于memset
Arrays.fill(bMax, Integer.MIN_VALUE);
for(int i = 0; i < num.length; i++){
int temp = (num[i] - min) / len; //放入几号桶
bMin[temp] = Math.min(num[i], bMin[temp]); //bMin记录每个桶的最小值
bMax[temp] = Math.max(num[i], bMax[temp]); //bMax记录每个桶的最大值
}
int res = Integer.MIN_VALUE; //最后要求的最大距离
int pre = bMax[0];
for(int i = 1; i < n; i++){
if(bMin[i] == Integer.MAX_VALUE && bMax[i] == Integer.MIN_VALUE)
continue; //空桶不管它
res = Math.max(res, bMin[i] - pre);
pre = bMax[i];
}
res = Math.max(res, bMin[n] - pre);
return res;
}
Test
public static void main(String[] args){
int[] num = {34, 33, 100, 1};
System.out.println(new Solution().maximumGap(num));
}