leetcode——Maximum Gap


    想了一晚上沒想明白,上網搜了別人的答案。。。研究了好幾個晚上才覺得有點明悟了。。。

下面是詳細思考的過程:(參考答案

class Solution {
public:
    // 用桶排序
    // 算出相鄰兩個桶之間的最大差值
    // 如果是平均分布,則桶的數目和元素的數目相同時,其排序的時間復雜度是0(n)
    // 我們假設桶的個數和元素的數目相同,若是平均分布,則每個桶里有一個數,而若某個桶里有兩個以上的桶時,這時必有至少一個是空桶,那么最大間隔可能就落在空桶的相鄰兩個桶存儲的數之間,最大間隔不會落在同一個桶的數里,因此我們不需要對每個桶再排一次序,只需要記錄同一個桶的最大值和最小值,算出前一個有最大值的桶和后一個有最小值的桶之差,則可能是最大間隔
    //步驟:1.算好用的桶的個數,用最大元素和最小元素算出平均間隔,記錄在平均間隔上的最大值和最小值,
    // 2. 再算出前一個間隔里的最大值和后一個間隔里的最小值之差,取最大的一個,
    // 3. 再算出最小值和第二小的差(平均間隔最小值第一個),最大值和第二大(平均間隔最大值最后一個)的差,三個值相比,取最大的,就是最大間隔
    int maximumGap(vector<int> &num) {
        if (num.size() < 2) return 0;
        // 1. 算出用的桶數:取平均間隔,再用最大值和最小值之差除以間隔,得到桶數
        // 因為假設所有值都是平均分布的時候,如此取桶數可得時間復雜度是0(n)
        auto maxVal = *max_element(num.begin(), num.end());
        auto minVal = *min_element(num.begin(), num.end());
        int agGap = ceil((double)(maxVal - minVal) / (num.size()-1)); // 平均間隔
        int bucketCount = ceil((double)(maxVal - minVal) / agGap);
        // 2. 記錄每個桶的最大值和最小值
        vector<pair<int, int> > buckets(bucketCount, make_pair(INT_MIN, INT_MAX)); // 初始化桶
        for (auto val : num){
            if (val == maxVal || val == minVal) continue;
            int bucketNum = (val - minVal) / agGap;
            if (val > buckets[bucketNum].first) 
                buckets[bucketNum].first = val; // 存儲最大值
            if (val < buckets[bucketNum].second) buckets[bucketNum].second = val; // 存儲最小值
        }
        // 3. 算出最大間隔
        int maxGap(0), lastMax(minVal);
        for (auto bucket : buckets){
            if (bucket.first == INT_MIN) continue; // 空桶
            int curMax(bucket.first), curMin(bucket.second);
            maxGap = max(maxGap, curMin - lastMax);
            lastMax = curMax;
        }
        maxGap = max(maxGap, maxVal - lastMax);
        return maxGap;
    }
};


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM