标签:
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.
思路:题目要求一个无序数组排序后相邻两个元素的最大差值。
最简单的做法,对数组进行排序,然后对拍好序后的元素计算最大相邻差。一般的排序算法的时间复杂度是O(nlogn),不满足题目的O(n)时间复杂度。因此可以考虑选择用桶排序,需要确定如何划分桶。
1. 设max为排序后数组相邻两个元素的最大差;A,B为数组的最小,最大值,这两个值可以通过一次遍历数组得到。
则max=(B-A) / (A.length-1),如果不能整除,则向上取整。(如1~100的10个数,连续两个数的最大差值不可能小于10)。
我们用max作为一个桶的容量,则桶的个数count = (B-A) / max + 1,如果不能整除,向上取整。
所有的桶用bucket表示。
2. 对于每个桶,实际只需记录该桶内的最大值和最小值。由于一个桶内最多max个连续的数据,因此一个桶内的最大差值为max-1,所以整个数组的最大差值不可能出现在一个桶中,而应该是相邻桶的最小值与前一个桶的最大值的差。设第k个桶的最小值为bucket[k-1][0],最大值为bucket[k-1][1];
3. 对于数组中各每个元素,用th=(num[i] - A) / max来确定该元素所对应的桶。
4. 如果num[i]<bucket[k-1][0] ,更新bucket[k-1][0] = num[i];如果num[i]>bucket[k-1][1] ,更新bucket[k-1][1] = num[i];
5. 计算连续两个桶的最大差值,从而得到整个数组的最大差值。
代码如下:
public int maximumGap(int[] num) { if(num == null || num.length < 2) return 0; int min = num[0]; int max = num[0]; for(int i=1; i<num.length ;i++) { if(num[i] < min) { min = num[i]; } if(num[i] > max) { max = num[i]; } } int length = (int) Math.ceil((double)(max-min) / (num.length-1)); int count = (int) Math.ceil((double)(max-min) / length) + 1; int[][] bucket = new int[count][2]; for(int i=0; i<num.length; i++) { int th = (num[i] - min) / length; if(num[i] < bucket[th][0] || min >= bucket[th][0]) bucket[th][0] = num[i]; if(num[i] > bucket[th][1]) bucket[th][1] = num[i]; } int gap = 0; int lastMax = bucket[0][1]; for(int i=1; i<count; i++) { if(bucket[i][0] > min) { if(bucket[i][0] - lastMax > gap) gap = bucket[i][0] - lastMax; lastMax = bucket[i][1]; } } return gap; }
标签:
原文地址:http://www.cnblogs.com/linxiong/p/4338310.html