public class Solution {
public int maximumGap(int[] num) {
int len = num.length;
if( len<2 )
{
return 0;
}
int MIN = Integer.MAX_VALUE;
int MAX = Integer.MIN_VALUE;
for(int n:num)
{
MIN = Math.min(MIN,n);
MAX = Math.max(MAX,n);
}
int gap = (int)Math.ceil( (double)(MAX-MIN)/(len-1) );
int[] buckmin = new int[len-1];
int[] buckmax = new int[len-1];
Arrays.fill(buckmin,Integer.MAX_VALUE);
Arrays.fill(buckmax,Integer.MIN_VALUE);
for(int n:num)
{
if(n==MIN||n==MAX)
{
continue;
}
int id = (n-MIN)/gap;
buckmin[id] = Math.min(buckmin[id],n);
buckmax[id] = Math.max(buckmax[id],n);
}
int ret = Integer.MIN_VALUE;
int pre = MIN;
for(int i=0;i<len-1;i++)
{
if(buckmin[i]==Integer.MAX_VALUE&&buckmax[i]==Integer.MIN_VALUE)
{
continue;
}
ret = Math.max(ret,buckmin[i]-pre);
pre = buckmax[i];
}
ret = Math.max(ret,MAX-pre);
return ret;
}
}
题目要求我们在线性时间和空间条件下求出一个无序数组在有序情况下间隔最大的相邻元素.....最显然的方法就是先排序再遍历一边,但是代价是O(nlog),不是线性的。
标准答案采用了桶排序的思路....将这len个数放进len-1个桶中,每个桶的大小是(max-min)/(len-1),那么显然桶内的各个数之间的差距不可能是全局最大(小于平均值),因而桶内只需维护最大最小值即可,无需排序。之后再遍历各个桶,比较相邻桶最大最小值(肯定是相邻的)之间的差即可得到相邻最大差的数。
注意的是最后别忘了max和最大的桶的max之间的差。