LeetCode – Maximum Gap (Java)

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.

Analysis

We can use a bucket-sort like algorithm to solve this problem in time of O(n) and space O(n). The basic idea is to project each element of the array to an array of buckets. Each bucket tracks the maximum and minimum elements. Finally, scanning the bucket list, we can get the maximum gap.

The key part is to get the interval:

From: interval * (num[i] - min) = 0 and interval * (max -num[i]) = n
interval = num.length / (max - min)

The following diagram shows an example.

Java Solution

class Bucket{
    int low;
    int high;
    public Bucket(){
        low = -1;
        high = -1; 
    }
}
 
public int maximumGap(int[] num) {
    if(num == null || num.length < 2){
        return 0;
    }
 
    int max = num[0];
    int min = num[0];
    for(int i=1; i<num.length; i++){
        max = Math.max(max, num[i]);
        min = Math.min(min, num[i]);
    }
 
    // initialize an array of buckets
    Bucket[] buckets = new Bucket[num.length+1]; //project to (0 - n)
    for(int i=0; i<buckets.length; i++){
        buckets[i] = new Bucket();
    }
 
    double interval = (double) num.length / (max - min);
    //distribute every number to a bucket array
    for(int i=0; i<num.length; i++){
        int index = (int) ((num[i] - min) * interval);
 
        if(buckets[index].low == -1){
            buckets[index].low = num[i];
            buckets[index].high = num[i];
        }else{
            buckets[index].low = Math.min(buckets[index].low, num[i]);
            buckets[index].high = Math.max(buckets[index].high, num[i]);
        }
    }
 
    //scan buckets to find maximum gap
    int result = 0;
    int prev = buckets[0].high;
    for(int i=1; i<buckets.length; i++){
        if(buckets[i].low != -1){
            result = Math.max(result, buckets[i].low-prev);
            prev = buckets[i].high;
        }
 
    }
 
    return result;
}

10 thoughts on “LeetCode – Maximum Gap (Java)”

  1. =bucketing or hashing

    =1 we can solve this using sorting, n lg n , or linear.

    =2
    or using hashing, put all elements in hash, and just traverse from min to max, each step, fixing diff. problem it is too long upto n^32 steps (max element)
    ========
    , so lets use buckets (1 or 5 or 10 pct, any number reasonable), insert each element in bucket, keep min-max per bucket, and keep 2d hash what bucket is used or not.

    so, after per each used bucket (=where elements are), per each min-max per bucket, traverse all elements form min to max, and keep max diff.

    I AM STILL NOT CONVINCED ABOUT COMPARING bucket_next.min w/ bucket_curr.max
    as in solution!

  2. what about div/ conq, nonlinear solution?

    lets say array sorted, so biggest gap is
    divide in 2 halfs, 2 elements either in left, or right half, or
    it is biggest element in left, and smallest in right (=bigger) half

    combine!!!!

  3. well, i am no convinced..

    this algo is based on that bucket[i].max – bucket[i+1].min is always answer!

    but why? so there is such pair inside single bucket that is result? why?

    it is possible, but not clear!!

  4. Yes, This is what i have tried and failed, since you can’t declare an array of size more than 10^6 you can’t map values like 10^9 . So segmentation fault happens. 🙂

  5. If I use a BitSet(or a bit array). Iterate through the numbers marking each corresponding bit for each integer that I encounter then iterate through the BitSet to find the maximum gap wouldn’t it work in 2n time? For eg. if there is a number set 1,100,5. I iterate through the list and mark out bits 1, 100 and 5. During the same process I will get the minimum and maximum which is 1 and 100. Then I iterate through the bitset from minimum(1) to maximum(100) marking out the largest gap. First I hit upon 4 (5-1) and then 95(100-5). When I hit the maximum number I stop and return the maximum gap.

  6. Anushree, the output is 21 because when the array is sorted it will be {3,5,9,30,34}. Max difference between consecutive elements is 30-9 which is 21. If you do radix sort, you will need to sort all the way through (sort each digit in the integer) to get the sorted array, not just the first position. I hope this helps..

  7. I did not understand the problem statement itself. From https://leetcode.com/discuss/18501/dont-understand-the-problem it seems like we need to do radix sort first and then calculate the maximum gap. But when i ran the code given here against the input (3,30,34,5,9), i am getting the output as 21. i dont understand it. If we do radix sort the input, it becomes (3,30,34,5,9) and the answer should be (34-5) = 29. how is it 21? please explain.

Leave a Comment