Maximum Gap

Given an integer array nums return the maximum difference between two successive elements in its sorted form.

Alkesh Ghorpade
Nerd For Tech
8 min readJun 25, 2023

--

Problem statement

Given an integer array nums, return the maximum difference between two successive elements in its sorted form. If the array contains less than two elements, return 0.

You must write an algorithm that runs in linear time and uses linear extra space.

Problem statement taken from: https://leetcode.com/problems/maximum-gap.

Example 1:

Example 2:

Constraints:

Solution

Approach 1: Brute force

The brute force approach sorts the array and finds the maximum difference between two adjacent elements. The time complexity of this approach is O(n), and the space complexity is O(1).

A C++ snippet of this approach is as below:

int maximumGap(vector<int>& nums) {
int n = nums.size();

if(n <= 1) {
return 0;
}

sort(nums.begin(), nums.end());
int maxDifference = INT_MIN;

for(int i = 0; i < n - 1; i++) {
maxDifference = max(maxDifference, nums[i + 1] - nums[i]);
}

return maxDifference;
}

Approach 2: Pigeonhole Sorting

The problem statement mentions solving the problem in linear time, using linear extra space. We can use the concept of Pigeonhole Sorting. Pigeonhole algorithm is suitable for sorting lists of elements where the number of elements and possible key values is approximately the same. It requires O(n + Range) time, where n is the number of elements in the input array and Range is the number of possible values in the array.

The flow of this algorithm is as follows:

We apply the above approach to find the maximum gap between two successive elements in the sorted array.

Let’s check the algorithm.

Algorithm

The time complexity of this approach is O(n), and the space complexity if O(n).

Let’s check out our solutions in C++, Golang, and Javascript.

C++ solution

class Solution {
public:
int maximumGap(vector<int>& nums) {
int maximum = nums[0], minimum = nums[0];
int n = nums.size(), i;

if(n <= 1) {
return 0;
}

// find the maximum and minimum in nums[]
for(int i = 1; i < n; i++) {
maximum = max(maximum, nums[i]);
minimum = min(minimum, nums[i]);
}

// create arrays to store maximum and minimum values in n-1 buckets of range.
vector<int> maxBucket(n - 1, INT_MIN);
vector<int> minBucket(n - 1, INT_MAX);

// calculate the range
int range = ceil((maximum - minimum) / (n - 1));

// traverse through the input array and insert the element in the appropriate bucket
// if the bucket is empty else, update bucket values
for (i = 0; i < n; i++) {
if (nums[i] == maximum || nums[i] == minimum)
continue;

// compute the index of the bucket
int index = ((nums[i] - minimum) / range);

maxBucket[index] = max(maxBucket[index], nums[i]);
minBucket[index] = min(minBucket[index], nums[i]);
}

// find the maximum gap between the maximum value
// of the previous bucket minus a minimum of the current bucket.
int previousValue = minimum;
int maximumGap = 0;

for (i = 0; i < n - 1; i++) {
if (minBucket[i] == INT_MAX)
continue;

maximumGap = max(maximumGap, minBucket[i] - previousValue);
previousValue = maxBucket[i];
}

maximumGap = max(maximumGap, maximum - previousValue);

return maximumGap;
}
};

Go solution

func maximumGap(nums []int) int {
maximum, minimum := nums[0], nums[0]
n, i := len(nums), 0

if n <= 1 {
return 0
}

// find the maximum and minimum in nums[]
for i = 1; i < n; i++ {
maximum = max(maximum, nums[i])
minimum = min(minimum, nums[i])
}

// create arrays to store maximum and minimum values in n-1 buckets of range.
maxBucket := make([]int, n - 1)
minBucket := make([]int, n - 1)

for j := range maxBucket {
maxBucket[j] = math.MinInt32
minBucket[j] = math.MaxInt32
}

// calculate the range
rangeValue := int(math.Ceil(float64(maximum - minimum) / float64(n - 1)))

// traverse through the input array and insert the element in the appropriate bucket
// if the bucket is empty else, update bucket values
for i = 0; i < n; i++ {
if nums[i] == maximum || nums[i] == minimum {
continue
}

index := ((nums[i] - minimum) / rangeValue)

maxBucket[index] = max(maxBucket[index], nums[i])
minBucket[index] = min(minBucket[index], nums[i])
}

// find the maximum gap between the maximum value
// of the previous bucket minus a minimum of the current bucket
previousValue, maximumGap := minimum, 0

for i = 0; i < n - 1; i++ {
if minBucket[i] == math.MaxInt32 {
continue
}

maximumGap = max(maximumGap, minBucket[i] - previousValue)
previousValue = maxBucket[i]
}

return max(maximumGap, maximum - previousValue)
}

func max(a, b int) int {
if a > b {
return a
}

return b
}

func min(a, b int) int {
if a < b {
return a
}

return b
}

JavaScript solution

/**
* @param {number[]} nums
* @return {number}
*/
var maximumGap = function(nums) {
let maximum = nums[0], minimum = nums[0];
let n = nums.length, i;

if(n <= 1) {
return 0;
}

// find the maximum and minimum in nums[]
for(i = 1; i < n; i++) {
maximum = Math.max(maximum, nums[i]);
minimum = Math.min(minimum, nums[i]);
}

// create arrays to store maximum and minimum values in n-1 buckets of range.
let maxBucket = new Array(n - 1).fill(Number.MIN_SAFE_INTEGER);
let minBucket = new Array(n - 1).fill(Number.MAX_SAFE_INTEGER);

// calculate the range
let range = Math.ceil((maximum - minimum) / (n - 1));

// traverse through the input array and insert the element in the appropriate bucket
// if the bucket is empty else, update bucket values
for (i = 0; i < n; i++) {
if (nums[i] == maximum || nums[i] == minimum)
continue;

// compute the index of the bucket
let index = ((nums[i] - minimum) / range);

maxBucket[index] = Math.max(maxBucket[index], nums[i]);
minBucket[index] = Math.min(minBucket[index], nums[i]);
}

// find the maximum gap between the maximum value
// of the previous bucket minus a minimum of the current bucket.
let previousValue = minimum;
let maximumGap = 0;

for (i = 0; i < n - 1; i++) {
if (minBucket[i] == Number.MAX_SAFE_INTEGER)
continue;

maximumGap = Math.max(maximumGap, minBucket[i] - previousValue);
previousValue = maxBucket[i];
}

maximumGap = Math.max(maximumGap, maximum - previousValue);

return maximumGap;
};

Dry Run

Let’s dry-run our algorithm to see how the solution works.

Originally posted at https://alkeshghorpade.me.

--

--