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.


題意:

給定一個數組,找出該數組排序後兩兩數字之間的最大差值。

解題思路;
1.最先想到的就是排序,然後計算兩兩之間的差值。     時間複雜度: O(nlogn)
2. 開闢一個INT_MAX大小的空間,然後將存在的元素置true, 再計算兩兩之間的差值。  但是這樣會超時,爲什麼呢?因爲開闢空間太大啦
3.那就對上面改進一下咯,其實範圍不需要這麼大,找到數組中最大值和最小值,因此需開闢最大值-最小值的空間範圍.
但是。。。。。空間超了額。。。

下面是代碼:正確的,但是空間超了
class Solution {
public:
    int maximumGap(vector<int>& nums) {
        if(nums.size() < 2) return 0;
        int maxn = INT_MIN, minn = INT_MAX;
        for(int i = 0; i < nums.size(); i++){
            if(nums[i] < minn)
                minn = nums[i];
            if(nums[i] > maxn)
                maxn = nums[i];
        }
        int gap = maxn - minn+1;
        vector<int>vec(gap,0);
        for(int i = 0; i < nums.size(); i++){
            vec[nums[i] - minn]++;
        }
        int last = 0, ma = -1;
        for(int i = 1; i < gap; i++){
            if(vec[i] > 0){
                ma = max(ma, i-last);
                last = i;
            }
        }
        

        return ma;
    }
};




3.別人的思路   桶排序 那就只能把空間範圍再次縮小啦~~

解題思路:

基數排序(radix sort)/桶排序(bucket sort)

官方版(桶排序):

假設有N個元素A到B。

那麼最大差值不會小於ceiling[(B - A) / (N - 1)]

令bucket(桶)的大小len = ceiling[(B - A) / (N - 1)],則最多會有(B - A) / len + 1個桶

對於數組中的任意整數K,很容易通過算式loc = (K - A) / len找出其桶的位置,然後維護每一個桶的最大值和最小值

由於同一個桶內的元素之間的差值至多爲len - 1,因此最終答案不會從同一個桶中選擇。

對於每一個非空的桶p,找出下一個非空的桶q,則q.min - p.max可能就是備選答案。返回所有這些可能值中的最大值。


下面是代碼

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        if(nums.size() < 2) return 0;
        double maxn = INT_MIN, minn = INT_MAX, len = nums.size();
        for(int i = 0; i < nums.size(); i++){
            if(nums[i] < minn)
                minn = nums[i];
            if(nums[i] > maxn)
                maxn = nums[i];
        }
        int bucket_size = ceil((maxn - minn)/(len-1)); //桶的大小  出錯2
        if(bucket_size == 0) return 0; //出錯1
        int bucket_num = (maxn-minn)/bucket_size+1; //桶的個數
        vector<vector<int>>vec(bucket_num,vector<int>());
        for(int i = 0; i < nums.size(); i++){
            vec[(nums[i] - minn)/bucket_size].push_back(nums[i]);
        }
        int pre_max = 0, res = 0;
        for(int i = 0; i < bucket_num; i++){
            int cur_min = INT_MAX, cur_max = 0;
            for(int j = 0; j < vec[i].size(); j++){
                if(vec[i][j] > cur_max)
                    cur_max = vec[i][j];
                if(vec[i][j] < cur_min)
                    cur_min = vec[i][j];
            }
            if(vec[i].size() > 0){ //出錯3
                 if(i > 0) //出錯4
                    res = max(res, cur_min - pre_max);
                pre_max = cur_max;
            }
        }
        return res;
    }
};


儘管根據上面的來寫代碼,但是仍然有些小trips的地方出錯:

出錯1: 對於【1,1,1,1】 這種case,  沒有對bucket_size=0進行驗證,導致運行bucket_num時分母爲0,出錯;
出錯2:開始時計算bucket_size時, 沒有用ceil,導致對於【1,1,1,1,5,5,5,5】這種case,運行出的bucket_size爲0;
出錯3:由於有些桶存在個數爲0的情況,因此需要跳過這種情況,即加入判斷 if(vec[i].size() > 0)

出錯4:因爲我是計算當前的最小值與前面最大值的差值,因此對於第0號的bucket_num, 它前面的最大值是不知道的,因此需要跳過去,因此要加入if(i>0)




發佈了171 篇原創文章 · 獲贊 7 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章