Skip to content

0164. Maximum Gap

Given an unsorted array, find the maximum difference between the successive elements in its sorted form.

Return 0 if the array contains less than 2 elements.

Example 1:

Input: [3,6,9,1]
Output: 3
Explanation: The sorted form of the array is [1,3,6,9], either
             (3,6) or (6,9) has the maximum difference 3.

Example 2:

Input: [10]
Output: 0
Explanation: The array contains less than 2 elements, therefore return 0.

Note:

  • You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
  • Try to solve it in linear time/space.

Analysis

Let's first split the array into multiple equal-size ranges, and the total number of ranges is n (the size of the input array).

3, 6, 9, 1
-> we have 4 numbers, so we will have four ranges
(] (] (] (] 

Because we have n ranges, if we can know how big is each range, we can place each number to its correct range. For each range, we will keep a record of the maximum difference between a current number and the sorted number.

3, 6, 9, 1
-> Let's assume the size of each range is len
(a, a + len] (b, b + len] (c, c + len] (d, d + len]

To determine which range should each number be placed into, we use a math trick:

idx = \frac{x-a-1}{n-1}, where a is the minimum value or the starting value of our ranges.

Given this information, we can just find and compare the maximum difference across every two ranges. Now we have n numbers, and there are len - 1 numbers in each range. If we have a relatively small length of each range, the maximum difference cannot exist in each range, but across two successive ranges.

(n-1)(len-1) < Max - Min, which yield

(Max - Min + n - 2)/(n - 1) after rearrangement.

  • Time: O(n)
  • Space: O(n)

Code

class Solution {
public:
    struct Range{
        int min,max;
        bool used;
        Range() : min(INT_MAX), max(INT_MIN), used(false) {}
    };
    int maximumGap(vector<int>& nums) {
        int n = nums.size();
        int Max = INT_MIN, Min = INT_MAX;
        for (int x : nums) {
            Max = max(Max, x);
            Min = min(Min, x);
        }
        if (n < 2 || Max == Min) return 0;
        vector<Range> r(n-1);
        // average size of each range to make sure 
        // global diff only exists in each range 
        // but not accross any two more more range
        int len = (Max-Min+n-2)/(n-1); 
        for (int x : nums) {
            if (x == Min) continue;
            int idx = (x-Min-1)/len;
            r[idx].min = min(r[idx].min,x);
            r[idx].max = max(r[idx].max, x);
            r[idx].used = true;
        }
        int res = 0;
        for (int i = 0, last = Min; i < n - 1; ++i) {
            if (r[i].used) {
                res = max(res, r[i].min - last);
                last = r[i].max;                
            }
        }
        return res;

    }
};

Last update: April 1, 2022