最大差值(桶)

题目:给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。

已知的基于比较的排序,最快也要O(N*logN),所以即时不用非基于比较的排序,也一定要用到桶的概念。

首先准备桶,如果数组有N个数,就准备N+1个桶,先遍历数组,找最小值和最大值,如果min!=max,就把min放入0号桶,max放入N号桶,把min到max的范围,等分成N+1份,分别对应N+1个桶,剩下的数,属于哪个范围就放入哪个桶,这样,N+1个桶中必定存在至少一个空桶,这就使得我们所要求的最大差值,大与单个桶的差值范围,最大差值就一定不会来自同一个桶中的两个数,最大差值一定来自前一个桶的最大值和后一个桶的最小值。

那么我们每个桶,也之需要记录是否进来过数,以及进过它的最小值和最大值。

然后从1号桶开始搜索,如果它空的,就直接跳下一个,如果它是非空的桶,就找到它左边最近非空的桶,记录它左边最近非空桶的max和它自己min的差值,我们要求的最大差值,一定就是这些差值中的最大值

#include<iostream>
#include <vector>
#include <cstring>

using namespace std;
//判断一个数该进哪个桶
int bucket(long num,long len,long min,long max){
    return (int)((num-min)*len/(max-min));
}
int maxGap(vector<int>&nums){
    if(nums.empty()||nums.size()<2)
        return 0;
    int len=nums.size();
    int _min=10000;
    int _max=-10000;
    for(int i=0;i<len;i++){
        _min=min(_min,nums[i]);
        _max=max(_max,nums[i]);
    }
    if(_max==_min)
        return 0;
    bool hasNum[len+1];
    memset(hasNum, false,sizeof(hasNum));
    int maxes[len+1];
    int mins[len+1];
    int bid=0;
    for(int i=0;i<len;i++){
        bid=bucket(nums[i],len,_min,_max);
        mins[bid]=hasNum[bid]?min(mins[bid],nums[i]):nums[i];
        maxes[bid]=hasNum[bid]?max(maxes[bid],nums[i]):nums[i];
        hasNum[bid]=true;
    }
    int res=0;
    int lastMax=maxes[0];
    int i=1;
    for(;i<=len;i++){
        if(hasNum[i]){
            res=max(res,mins[i]-lastMax);
            lastMax=maxes[i];
        }
    }
    return res;
}
int main(){
    vector<int>nums={178,34,35,245,13,5,25,3};
    int ans=maxGap(nums);
    cout<<ans;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值