LeetCode---(164)Maximum Gap

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.

首先,我们很容易想到先对数组进行排序,得到有序数组,然后再对相邻元素做差,找出差值最大的

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        if(nums.size()<2)
            return 0;
        sort(nums.begin(),nums.end());
        int max=0;
        for(int i=1;i<nums.size();i++)
        {
            if(nums[i]-nums[i-1]>max)
                max=nums[i]-nums[i-1];
        }
        return max;
    }
};

虽然我们可以通过以上的代码,但是仔细看题目我们发现,我们并没有满足题目中所要求的时间复杂度( STL函数sort()的复杂度是O(nlogn)),然后我们考虑,可以借鉴桶排序的做法

思路是这样的:数组中有N个元素,最小的元素为min,最大的元素为max,那么最大的间距将不小于ceil((max-min)/(N-1))。(其中,ceil(x)指的是不小于x的最小整数)。假设平均间距为gap=ceil((max-min)/(N-1)),把所有的元素放进N-1个桶里,第k(0<=k<=N-2)个桶里放所有位于区间[min+k*gap, min+(k+1)*gap)内的元素。因此除了最大的元素max和最小的元素min,其余的N-2个元素都被放进这N-1个桶里,因此至少有一个桶是空的,我们只需要存储每个桶里最大的元素和最小的元素就可以算出最大的间距是多少。

具体代码如下

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        if(nums.size()<2)
            return 0;
        int min=nums[0],max=nums[0];
        int nSize=nums.size();
        for(int i=0;i<nSize;i++)
        {
            if(nums[i]<min)
                min=nums[i];
            else if(nums[i]>max)
                max=nums[i];
        }
        if(nSize==2)
            return max-min;
        //每个桶的大小,向上取整。
        int bucket_length=(max-min)/(nSize-1)+1;   
        //桶的个数:(max - min) / bucket_length + 1,每个桶里面存储属于该桶的最大值和最小值即可,注意这里的最大最小值是局部的 
        int bucket_num=(max - min) / bucket_length + 1;
        vector<vector<int>> bucket(bucket_num);
        for(int i=0;i<nSize;i++)
        {
            int index=(nums[i]-min)/bucket_length;
            if(bucket[index].empty()){
                bucket[index].reserve(2);
                bucket[index].push_back(nums[i]);
                bucket[index].push_back(nums[i]);
            }else{
                if(bucket[index][0]>nums[i])
                    bucket[index][0]=nums[i];
                if(bucket[index][1]<nums[i])
                    bucket[index][1]=nums[i];
            }
        }
        int res=0;
        int pre=0;
        for(int i=1;i<bucket.size();i++)
        {
            if(bucket[i].empty())
                continue;
            if(bucket[i][0]-bucket[pre][1]>res)
                res=bucket[i][0]-bucket[pre][1];
            pre=i;
        }
        return res;
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值