Maximum Gap

来源:互联网 发布:传奇霸业帝陨宝石 数据 编辑:程序博客网 时间:2024/05/22 14:54

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.

这道题的意思就是,给定未排序的数组,求解该数组排序后,相邻两个数最大的差值。
很明显我们会直接想到将这个序列排列后,在求解,但是一般的排序都是O(nlogn)的复杂度。
这时候从题中我们可以看到允许使用额外的线性空间,这时我们就会想到基数排序,桶排序,具体可以参见链接的博文
首先我们给出桶排序的代码:
class Solution {public:    int maximumGap(vector<int> &num) {        int n = num.size();        if(n<2) return 0;        int maxValue = num[0],minValue=num[0];        for(int i = 1;i<n;i++)        {            maxValue = max(maxValue,num[i]);            minValue = min(minValue,num[i]);        }        if(maxValue==minValue) return 0;        double gap = (maxValue-minValue)*1.0/(n-1);        vector<int> buckets(2*n,-1);        for(int i = 0;i<n;i++)        {            int ind = int((num[i]-minValue)/gap);            ind = 2 * ind;            buckets[ind] = buckets[ind] == -1 ? num[i] : min(buckets[ind], num[i]);            buckets[ind+1] = buckets[ind+1] == -1 ? num[i] : max(buckets[ind+1], num[i]);        }        int ans = 0;        int bound = minValue;        for(int i = 0;i<2*n;i+=2)        {            if(buckets[i]==-1)                continue;            ans = max(ans,buckets[i] - bound);            bound = buckets[i+1];        }        return ans;    }};
在桶排序中可能会有个疑惑,为什么我只用求两个桶间的最大值,而不管同一个桶中的距离呢?大家可以想想,同一个桶中,最大的距离就是一个gap
而不同桶间,最小的距离是gap,理由可想而知

下面是基数排序radix sort
base = 10
class Solution {public:    int maximumGap(vector<int> &num) {        int n = num.size();        if(n<2) return 0;        int maxValue = num[0];        for(int i = 1;i<n;i++)            maxValue = max(maxValue,num[i]);                int base = 10;        vector<vector<int> > buckets(base);        vector<int> copy(num);        for(long long i = 1;i<=maxValue;i*=10)        {            for(auto x : copy)            {                int index = x / i % base;                buckets[index].push_back(x);            }            for (int j = 0, k = 0; j < buckets.size(); j++)            {                for (int x : buckets[j]) copy[k++] = x;                buckets[j].clear();            }        }                int ans = 0;        for (int i = 1; i < copy.size(); i++) {            int gap = copy[i] - copy[i-1];            ans = max(ans,gap);        }        return ans;    }};
后来在网上看到了个base等于0的算法,代码异常简单
int maximumGap(std::vector<int> &num) {    for(unsigned bit = 0; bit < 31; bit++)    std::stable_partition(num.begin(), num.end(), [bit](int a){        return !(a & (1 << bit));    });    int difference = 0;    for(std::size_t i = 1; i < num.size(); i++) {        difference = std::max(difference, num[i] - num[i-1]);    }    return difference;}
stable_partition (beg, end, unaryPred) ;
// 操作前:[beg,end)标示输入序列.unaryP是一元函数对象.
// 操作后:使用unaryP划分输入序列.使unaryPred返回true的元素放在序列的开头.
// 使unaryPred为假的元素放在序列末尾.
// 返回值:返回一个迭代器,该迭代器指向使unaryPred为真的最后元素的下一个位置.
// 备注: 此划分算法为稳定算法.




0 0