您的位置:首页 > 其它

[Leetcode] maximum gap

2015-08-20 15:17 323 查看
[1] https://leetcode.com/problems/maximum-gap/

这里具有使用桶的思想来对整数进行规整,通过详细的设计桶的大小,可以保证最大间隔一定大于等于桶的大小,从而保证最大间隔不会出现在桶的内部,而是桶之间。

这里的关键是如何设计桶的大小?

假设N个数字,均等分布,那么间隔是(max - min)/(N-1)

如果不是均等分布,一定存在大于(max - min)/(N-1)的间隔。

所以最大的间隔一定大于等于(max - min)/(N-1)

上面的证明,实际上有一个非常强的前提:(max - min)%(N-1)==0,但是实际当中并不一定是整除的情形,这时我们要对这个间隔上取整,即

ceil((max - min)/(N-1))

我是亮丽的分割线

证明:

假设所有的gap都是小于等于floor((max - min)/(N-1))的,那么

$min + \sum_{i=1}^{N-1}gap \le max$

所以至少存在一个gap大于$floor((max - min)/(N-1))$的,或者是大于等于$ceil((max - min)/(N-1))$的

这说明最大的gap不会比$ceil((max - min)/(N-1))$小。

在桶的内部,gap都是小于这个值得,所以最大的gap只能存在于桶之间。

这里的$ceil((max - min)/(N-1))$是一个非常极端的情况,桶只要尽可能的小都是对的,比如$ceil((max - min)/N)$

public class Solution {
public int maximumGap(int[] nums) {
if(nums==null||nums.length==0||nums.length==1) return 0;
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for(int i: nums){
max = Math.max(max,i);
min = Math.min(min,i);
}
//backet size应该尽量小
//
int backetsize = (int)Math.ceil((double)(max - min)/(nums.length));
int [] maxmin = new int[3* nums.length];
for(int i=0;i<maxmin.length;i++) maxmin[i]=-1;
for(int i=0;i<nums.length;i++){
int num = nums[i];
int backetindex = (num - min)/backetsize;
if(maxmin[backetindex*2]==-1){
maxmin[backetindex*2]=maxmin[backetindex*2+1]=num;
}else{
maxmin[backetindex*2+1] = Math.max(maxmin[backetindex*2+1],num);
maxmin[backetindex*2] =   Math.min(maxmin[backetindex*2],num);
}
}
//search for the maximum gap
int pre = -1;
int maxgap = -1;
for(int i=0;i<nums.length;i++){
if(maxmin[2*i+1]!=-1&&pre==-1){
pre =maxmin[2*i+1];
continue;
}
if(maxmin[2*i]!=-1){
maxgap = Math.max(maxgap,maxmin[2*i]-pre);
pre = maxmin[2*i+1];
}
}
return maxgap;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: