[Leetcode] Maximum Gap 相鄰最大差值

weixin_34127717發表於2016-06-21

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.

桶排序

複雜度

O(N) 時間 O(N) 空間

思路

假設有N個元素A到B。

那麼最大差值一定大於floor[(B - A) / (N - 1)],floor就是向下取整

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

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

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

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

注意

注意特殊情況

程式碼

主程式:

public int maximumGap(int[] nums) {
    int n = nums.length;
    if (n <= 1)
        return 0;
    int max = getMax(nums);
    int min = getMin(nums);
    int len = (max - min) / (n - 1);//桶長
    if (len == 0)
        return max - min;
    int k = ((max - min) / len) + 1;//桶數
    Bucket[] buckets = new Bucket[k];
    init(buckets, min, len);
    fill(buckets, nums, min, len);
    int maxGap = find(buckets);
    return maxGap;
}

Utilities:

public int getMax(int[] nums) {
    int max = Integer.MIN_VALUE;
    for (int cur : nums)
        max = Math.max(cur, max);
    return max;
}

public int getMin(int[] nums) {
    int min = Integer.MAX_VALUE;
    for (int cur : nums)
        min = Math.min(cur, min);
    return min;
}

public int find(Bucket[] buckets) {
    int premax = Integer.MIN_VALUE;
    int curmin = Integer.MAX_VALUE;
    int max = Integer.MIN_VALUE;
    for (int i = 0; i < buckets.length; i++) {
        if (buckets[i].min != Integer.MAX_VALUE)
            curmin = buckets[i].min;
        if (premax != Integer.MIN_VALUE && curmin != Integer.MAX_VALUE)
            max = Math.max(curmin - premax, max);
        if (buckets[i].max != Integer.MIN_VALUE)
            premax = buckets[i].max;
    }
    return max;
}

public void fill(Bucket[] buckets, int[] nums, int min, int len) {
    for (int cur : nums) {
        int whichBucket = (cur - min) / len;
        buckets[whichBucket].max = Math.max(buckets[whichBucket].max, cur);
        buckets[whichBucket].min = Math.min(buckets[whichBucket].min, cur);
    }
}

public void init(Bucket[] buckets, int min, int len) {
    for (int i = 0; i < buckets.length; i++) {
        buckets[i] = new Bucket(min, min + len - 1);
        min = min + len;
    }
}

Bucket類:

class Bucket {
    int left;//inclusive,其實這個是沒必要的
    int right;//inclusive,其實這個是沒必要的
    int max;
    int min;
    Bucket(int left, int right) {
        this.left = left;
        this.right = right;
        this.max = Integer.MIN_VALUE;
        this.min = Integer.MAX_VALUE;
    }
}

相關文章