最大间距(基数排序/桶排/分块)

题目:https://leetcode-cn.com/problems/maximum-gap/
参考:https://leetcode-cn.com/problems/maximum-gap/solution/zui-da-jian-ju-by-leetcode/
被教育了orz
题意:给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。如果数组元素个数小于 2,则返回 0。要求时间和空间复杂度为O(n)。
先来恶补下基数排序的做法_(:з」∠)_,正解在下面。

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        int n = nums.size();
        if(n < 2) return 0;
        int lo = nums[0], hi = nums[0];
        for(int i = 0;i < n;i++) {
            lo = min(lo,nums[i]);
            hi = max(hi,nums[i]);
        }
        if(hi == lo) return 0;
        int base = 1;
        int count[10]={};
        int rank[n];
        while(hi/base) {
            for(int i = 0;i < 10;i++) count[i] = 0;
            for(int i = 0;i < n;i++) {
                count[(nums[i]/base)%10]++;
            }
            for(int i = 1;i < 10;i++) count[i] += count[i-1];
            for(int i = n-1;i >= 0;i--) 
                rank[--count[(nums[i]/base)%10]] = nums[i];
            for(int i = 0;i < n;i++)
                nums[i] = rank[i];
            base *= 10;
        }
        int ans = 0;
        for(int i = 1;i < n;i++)
            ans = max(ans,nums[i]-nums[i-1]);
        return ans;
    }
};

思路:找出最大值 h i hi 和最小值 l o lo ,那么最理想情况下,所有数间隔都相同,此时存在最大间隔最小取值 ( h i l o ) / ( n 1 ) (hi-lo)/(n-1) (向上取整);那么我们可以把这n个数分块,每个块大小取 ( h i l o ) / ( n 1 ) (hi-lo)/(n-1) (向下取整),那么答案最大间隔值肯定是存在于块间的数,因为块内数的差值<=最大间隔最小取值。

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        int n = nums.size();
        if(n < 2) return 0;
        int lo = nums[0], hi = nums[0];
        for(int i = 0;i < n;i++) {
            lo = min(lo,nums[i]);
            hi = max(hi,nums[i]);
        }
        if(hi == lo) return 0;
        int block = max(1,(hi-lo)/(n-1));//每个块大小
        int sz = (hi-lo)/block+1;//总块数
        int mn[sz],mx[sz];
        bool vis[sz];
        for(int i = 0;i < sz;i++) {
            mn[i] = INT_MAX;
            mx[i] = INT_MIN;
            vis[i] = 0;
        }
        for(int i = 0,id;i < n;i++) {
            id = (nums[i] - lo)/block;
            vis[id] = 1;
            mn[id] = min(mn[id],nums[i]);
            mx[id] = max(mx[id],nums[i]);
        }
        int pre = lo;
        int ans = 0;
        for(int i = 0;i < sz;i++) {
            if(!vis[i]) continue;
            ans = max(ans,mn[i]-pre);
            pre = mx[i];
        }
        return ans;
    }
};
发布了152 篇原创文章 · 获赞 2 · 访问量 6453

猜你喜欢

转载自blog.csdn.net/weixin_43918473/article/details/104690386