最大間隔(ベースソーティング/バレルローイング/ブロッキング)

タイトル: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 こんにちは と最小値 l なに 、理想的な条件下では、すべての間隔は同じです。このとき、最大間隔の最小値があります。 h l / 1 (ハイロー)/(N-1) (切り上げ);次に、これらのn個の数値をブロックに分割できます。各ブロックサイズが取得されます h l / 1 (ハイロー)/(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