1. 程式人生 > >【LeetCode】164. 最大間距 結題報告 (C++)

【LeetCode】164. 最大間距 結題報告 (C++)

原題地址:https://leetcode-cn.com/problems/maximum-gap/description/

題目描述:

給定一個無序的陣列,找出陣列在排序之後,相鄰元素之間最大的差值。

如果陣列元素個數小於 2,則返回 0。

示例 1:

輸入: [3,6,9,1]
輸出: 3
解釋: 排序後的陣列是 [1,3,6,9], 其中相鄰元素 (3,6) 和 (6,9) 之間都存在最大差值 3。
示例 2:

輸入: [10]
輸出: 0
解釋: 陣列元素個數小於 2,因此返回 0。
說明:

你可以假設陣列中所有元素都是非負整數,且數值在 32 位有符號整數範圍內。
請嘗試線上性時間複雜度和空間複雜度的條件下解決此問題。

 

解題方案:

本題有些難,屬於排序型別的題目,題目要求時間複雜度是線性的,就不能先對陣列進行排序再進行查詢最大差值。沒有很好的思路,在網上查到了一個方法,採用的是桶排序。參考地址:https://blog.csdn.net/zxzxzx0119/article/details/82889998

桶排序第一次遇到,當然就不會做了,就當是學習啦。

程式碼:

class Solution {
public:
    int mapToBucket(long num, long len, long min, long max){
        return int((num - min) * len / (max - min));
    }

    int maximumGap(vector<int>& nums) {
        if(nums.size() < 2)
            return 0;
        
        int len = nums.size();
        int a = nums[0], b = nums[0];
        for(int i = 0; i < len; i++){
            a = nums[i] < a ? nums[i] : a;
            b = nums[i] > b ? nums[i] : b;
        }
        if(a == b)
            return 0;
        
        //準備 n + 1個桶
        bool hasNum[len + 1] ;
        int mins[len + 1];
        int maxs[len + 1];

        for(int i = 0; i <= len; i++)
            hasNum[i] = false;
        for(int i = 0; i < len; i++){
            int bid = mapToBucket(nums[i], len, a, b);
            mins[bid] = hasNum[bid] ? min(mins[bid], nums[i]) : nums[i];
            maxs[bid] = hasNum[bid] ? max(maxs[bid], nums[i]) : nums[i];
            hasNum[bid] = true;
        }

        int res = 0, preMax = maxs[0]; //第一個桶一定不空  因為一定有一個 最小值

        // 每一個非空桶 都找到 左邊離它最近的非空桶  然後計算答案
        for(int i = 1; i <= len; i++){
            if(hasNum[i]) { // 是非空的
                res = max(res, mins[i] - preMax);
                preMax = maxs[i];
            }
        }
        return res;
    }
};