1. 程式人生 > >LeetCode164——最大間距

LeetCode164——最大間距

我的LeetCode程式碼倉:https://github.com/617076674/LeetCode

原題連結:https://leetcode-cn.com/problems/maximum-gap/description/

題目描述:

知識點:桶排序

思路:桶排序

如果陣列中的元素個數小於2,直接返回0即可。

對於n(n >= 2)個元素,假設其中的最大值是max,最小值是min。

如果max和min相等,顯然我們應該返回0。

否則,為其準備n + 1個桶,每個桶中的數字區間儘量平均分配,即第一個桶中存放[min, min + capacity)區間內的數字,最後一個桶中存放[max - capacity, max]區間內的數字。顯然,max和min已經保證了第一個桶和最後一個桶不是空桶。

顯然,將n個元素放進n + 1個桶裡,至少會有一個空桶同一個桶內的差值必然小於capacity,而間隔一個空桶的差值必然會大於capacity。因此,最大差值只可能在空桶的兩邊產生,即空桶的後一個非空桶的最小值減去空桶的前一個非空桶的最大值。

由此計算方式,我們也可以發現,我們無需儲存桶中的所有元素,只需儲存桶中的最大值和最小值即可,即陣列maxBuckets和minBuckets,其初始化均為-1,表示為空桶。

如何一次遍歷maxBuckets和minBuckets陣列來求出最大差值呢?

我們需要用一個pre指標儲存前一個非空桶的最大值,由於min一定在第一個桶,所以第一個桶一定非空,這為我們的計算帶來了方便。一旦遇到非空桶,我們就更新結果result和pre指標的值即可。

時間複雜度和空間複雜度均是O(n),其中n為陣列中的元素個數。

JAVA程式碼:

public class Solution {
    public int maximumGap(int[] nums) {
        if (nums.length < 2) {
            return 0;
        }
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > max) {
                max = nums[i];
            }
            if (nums[i] < min) {
                min = nums[i];
            }
        }
        if(min == max){
            return 0;
        }
        int[] maxBuckets = new int[nums.length + 1];
        Arrays.fill(maxBuckets, -1);
        int[] minBuckets = new int[nums.length + 1];
        Arrays.fill(minBuckets, -1);
        int capacity = (int) Math.ceil((double) (max - min) / (nums.length + 1));
        for (int i = 0; i < nums.length; i++) {
            int index = (nums[i] - min) / capacity;
            if (nums[i] == max) {   //最大值放進最後一個桶裡
                index = nums.length;
            }
            if (maxBuckets[index] == -1) {
                maxBuckets[index] = nums[i];
            } else if (nums[i] > maxBuckets[index]) {
                maxBuckets[index] = nums[i];
            }
            if (minBuckets[index] == -1) {
                minBuckets[index] = nums[i];
            } else if (nums[i] < minBuckets[index]) {
                minBuckets[index] = nums[i];
            }
        }
        int result = 0;
        int pre = maxBuckets[0];    //第一個桶有min,一定不是空桶
        for (int i = 1; i < maxBuckets.length; i++) {
            if (maxBuckets[i] != -1) {
                result = Math.max(result, minBuckets[i] - pre);
                pre = maxBuckets[i];
            }
        }
        return result;
    }
}

LeetCode解題報告: