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> &num) {  
        if(num.size()<2) return 0;  
        sort(num.begin(),num.end()); //O(nlogn)  
        int gap=-1;  
        for(int i=1;i<num.size();i++){  
            gap=max(gap,num[i]-num[i-1]);  
        }  
        return gap;  
    }  
};  

在Leetcode上上面的代码可以AC,但事实上并没有满足时间复杂度要求。因为STL函数sort()的复杂度是O(nlogn)。

那么,线性的排序算法有哪些?计数排序、基数排序、桶排序。
下面用桶排序实现,这也是leetcode上给出的参考解法,我直接copy过来:

解法二

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        if(nums.size() < 2 ) return 0;
        auto temp = std::minmax_element(nums.begin(), nums.end());
        int l = *temp.first; 
        int u = *temp.second;
        int bucket_gap = (u-l)/(nums.size()-1) >1? (u-l)/(nums.size()-1):1;
        int bucket_num = (u-l)/bucket_gap +1 ;
        std::vector<int> bucket_min(bucket_num,INT_MAX);
        std::vector<int> bucket_max(bucket_num,INT_MIN);
        for(auto num : nums) {
            int k = (num - l)/bucket_gap;
            bucket_min[k] = min(num,bucket_min[k]);
            bucket_max[k] = max(num,bucket_max[k]); 
        }
        int i = 0;
        int gap = bucket_max[0] - bucket_min[0];
        while(i < bucket_num-1) {
            int j = i+1;
            // check the jth bucket whether contains a num or not
            while (j < bucket_num && bucket_max[j] == INT_MIN  && bucket_min[j] == INT_MAX)
            j++;
            if(j==bucket_num) break;
            gap = max(gap, bucket_min[j] - bucket_max[i]);
            i = j;
        }
        return gap;
    }
};

比较有意思的是std::minmax_element函数,可以直接得到最小值和最大值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值