164. Maximum Gap [leetcode]

這道題可以有兩種剛解法:


解法一:

基於bucket sort的方法:

有n個未排序的數字。

1、先求出數組內最大數max和最小數min。

2、求出每個桶內的數字範圍:gap = (max - min) / (n - 1)。

3、算出桶的數量: N = (max - min)/ gap + 1  (可知 N >= n)

每個桶對應的數字範圍爲:

 第一個:[min, min + gap)

第二個:[min + gap, min + 2*gap)

......

第N個:[min + (N-1)gap, min + N*gap)

由於至少有n個桶。因此最平均的情況是每個桶裏一個數字。這時是要算出每個相鄰桶內數字的差即可得出結果。

若數字分佈不均勻,有若干個數字在同一個桶內。那麼一定起碼有一個桶是空的。存在兩個相鄰數字的差 > gap 。

因此只要通過記錄每個桶內最大數,和最小數。然後通過不斷比較第i個桶的最小值與前一個非空桶的最大值的差值,即可得到結果。

code如下:

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        if (nums.size() < 1) return 0;
        int res = 0;
        int maxV = INT_MIN, minV = INT_MAX, n = nums.size();
        for (auto i : nums) {
            maxV = max(maxV, i);
            minV = min(minV, i);
        }
        if (maxV == minV) return 0;
        int gap = (maxV - minV) / (n - 1) > 0 ?  (maxV - minV) / (n - 1) : 1;
        int bucketNum = (maxV - minV) / gap + 1;
        int *bucketMin = new int[bucketNum], * bucketMax = new int[bucketNum];
        for (int i = 0; i < bucketNum; i++) {
            bucketMin[i] = INT_MAX;
            bucketMax[i] = INT_MIN;
        }
        for (auto i : nums) {
            bucketMin[(i - minV) / gap] = min(i, bucketMin[(i - minV) / gap]);
            bucketMax[(i - minV) / gap] = max(i, bucketMax[(i - minV) / gap]);
        }
        int preIndex = 0;// 前一個非空桶的下標
        for (int i = 1; i < bucketNum; i++){
            if (bucketMin[i] == INT_MAX) continue;
            res = max(bucketMin[i] - bucketMax[preIndex], res);
            preIndex = i;
        }
        return res;
    }
};

方法二:

用radix sort先將整個數組排序。

radix sort的原理可以參考:

https://www.cs.usfca.edu/~galles/visualization/RadixSort.html


code:

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        if (nums.size() < 2) return 0;
       int res = 0, digit = 1, maxNum = INT_MAX;
        while(maxNum) {
            digit++;
            maxNum /= 10;
        }
        long k = 10;
        for (int j = 1 ; j <= digit; j++, k *= 10) {
            vector<int> tmp(nums.size(), 0);
            int count[10] = {0};
            for (auto num : nums) {
                 count[num % k / (k / 10)]++;
            }
            for(int i = 1; i < 10; i++)
                count[i] += count[i - 1];
            for (int i = nums.size() - 1; i >=0; i--) {
                int digit = nums[i] % k / (k / 10);
                tmp[count[digit] - 1] = nums[i];
                count[digit]--;
            }
            nums = tmp;
        }
        
        for (int i = 1; i < nums.size(); i++) 
            res = max(nums[i] - nums[i - 1], res);
        return res;
    }
};



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章