Open In App

Maximum adjacent difference in an array in its sorted form

Given an array arr[] of size N, find the maximum difference between its two consecutive elements in its sorted form.

Examples: 

Input: N = 3, arr[] = {1, 10, 5}
Output: 5
Explanation: Sorted array would be {1, 5, 10} and maximum adjacent difference would be 10 - 5 = 5

Input: N = 4, arr[] = {2, 4, 8, 11}
Output: 4
Explanation: Sorted array would be {2, 4, 8, 11} and the maximum adjacent difference would be 8 - 4 = 4

Recommended Practice

Naive Solution:

First sort the array, then traverse it and keep track of the maximum difference between adjacent elements. 
The time complexity of this method is O(nlogn).

Efficient Solution:
This solution is based on the idea of Pigeonhole sorting. No need to sort the array, just have to fill the buckets and keep track of the maximum and minimum value of each bucket. If found an empty bucket, The maximum gap would be the difference of maximum value in the previous bucket - minimum value in the next bucket.

As we want to almost sort these so that, we can have maximum gap. Also, for any ith element, the value of (arr[i]-min_value)/(max_value-min_value) keeps increasing as arr[i] keeps increasing and this value always varies from 0 to 1. As we want to put the sorted results in bucket of size n. We multiply this value by (n-1) hence make a variable delta = (max_value - min_value)/(n-1). Now in maxBucket or minBucket, all the value at any index j before index any i will always less than the value at index i, minBucket[j]<minBucket[i] for j<i. It is possible that two different arr[i], might have same value of (arr[i]-min_value)/delta, therefore we are making 2 different buckets maxBucket and minBucket.

As we have find the max difference between consecutive values, we must consider the max possible value upto to previous index as prev_val and the minBucket[i] for current index i, and ans will be max of ans and minBucket[i]-prev_val.

Let us solve the above example by this approach.

Working Example:

Input: arr[] = {1, 10, 5}

Output: 5

Step1: Find max_val and min_val 

max_val = 10, min_val = 1

Step2: Calculate delta

delta = (max_val - min_val)/(n-1)

delta = (10-1)/(3-1) = 4.5

Step3: Initialize buckets, maxBucket={INT_MIN}, minBucket={INT_MAX}

Step4: For any index i, calculate index arr[i] in bucket and update in buckets,

in = (arr[i]-min_val)/delta

maxBucket[in]=max(maxBucket[in],arr[i])

minBucket[in]=min(minBucket[in],arr[i])

for all index in arr in values are => 0,2,0

maxBucket=[5,INT_MIN,10]

minBucket=[1,INT_MAX,10]

Step5: Hence ans is max of minBucket[i]-(max of value upto previous index)

in this case for i=2: max_gap = max(max_gap,minBucket[2] - max(maxBucket[1],maxBucket[0]))

max_gap = 10-5=5

This is just for presenting the concept, all other basic validations are in the main code.

Below is the code for the above approach:

// CPP program to find maximum adjacent difference
// between two adjacent after sorting.
#include <bits/stdc++.h>
using namespace std;

int maxSortedAdjacentDiff(int* arr, int n)
{
    // If the array has no elements or a single element only
    if (n < 2)
        return 0;
    // Find maximum and minimum in arr[]
    int maxVal = arr[0], minVal = arr[0];
    for (int i = 1; i < n; i++) {
        maxVal = max(maxVal, arr[i]);
        minVal = min(minVal, arr[i]);
    }

    // Arrays to store maximum and minimum values
    // in n-1 buckets of differences.
    int maxBucket[n - 1];
    int minBucket[n - 1];
    fill_n(maxBucket, n - 1, INT_MIN);
    fill_n(minBucket, n - 1, INT_MAX);

    // Expected gap for every bucket.
    float delta = (float)(maxVal - minVal) / (float)(n - 1);

    // Traversing through array elements and
    // filling in appropriate bucket if bucket
    // is empty. Else updating bucket values.
    for (int i = 0; i < n; i++) {
        if (arr[i] == maxVal || arr[i] == minVal)
            continue;

        // Finding index of bucket.
        int index = (float)(floor(arr[i] - minVal) / delta);

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

    // Finding maximum difference between maximum value
    // of previous bucket minus minimum of current bucket.
    int prev_val = minVal;
    int max_gap = 0;
    for (int i = 0; i < n - 1; i++) {
        if (minBucket[i] == INT_MAX)
            continue;
        max_gap = max(max_gap, minBucket[i] - prev_val);
        prev_val = maxBucket[i];
    }
    max_gap = max(max_gap, maxVal - prev_val);

    return max_gap;
}

int main()
{
    int arr[] = { 1, 10, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << maxSortedAdjacentDiff(arr, n) << endl;
    return 0;
}
// Function to find maximum adjacent difference between two adjacent after sorting
function maxSortedAdjacentDiff(arr) {
    // If the array has no elements or a single element only
    if (arr.length < 2)
        return 0;

    // Find maximum and minimum in arr[]
    let maxVal = arr[0];
    let minVal = arr[0];
    for (let i = 1; i < arr.length; i++) {
        maxVal = Math.max(maxVal, arr[i]);
        minVal = Math.min(minVal, arr[i]);
    }

    // Arrays to store maximum and minimum values
    // in n-1 buckets of differences
    let maxBucket = new Array(arr.length - 1).fill(Number.MIN_SAFE_INTEGER);
    let minBucket = new Array(arr.length - 1).fill(Number.MAX_SAFE_INTEGER);

    // Expected gap for every bucket
    let delta = (maxVal - minVal) / (arr.length - 1);

    // Traversing through array elements and
    // filling in appropriate bucket if bucket
    // is empty. Else updating bucket values.
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] === maxVal || arr[i] === minVal)
            continue;

        // Finding index of bucket
        let index = Math.floor((arr[i] - minVal) / delta);

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

    // Finding maximum difference between maximum value
    // of previous bucket minus minimum of current bucket
    let prevVal = minVal;
    let maxGap = 0;
    for (let i = 0; i < arr.length - 1; i++) {
        if (minBucket[i] === Number.MAX_SAFE_INTEGER)
            continue;
        maxGap = Math.max(maxGap, minBucket[i] - prevVal);
        prevVal = maxBucket[i];
    }
    maxGap = Math.max(maxGap, maxVal - prevVal);

    return maxGap;
}

// Main function
function main() {
    let arr = [1, 10, 5];
    console.log(maxSortedAdjacentDiff(arr));
}

// Call the main function
main();
def max_sorted_adjacent_diff(arr):
    # If the array has no elements or a single element only
    if len(arr) < 2:
        return 0

    # Find maximum and minimum in arr[]
    max_val = max(arr)
    min_val = min(arr)

    # Arrays to store maximum and minimum values
    # in n-1 buckets of differences.
    max_bucket = [float('-inf')] * (len(arr) - 1)
    min_bucket = [float('inf')] * (len(arr) - 1)

    # Expected gap for every bucket.
    delta = (max_val - min_val) / (len(arr) - 1)

    # Traversing through array elements and
    # filling in appropriate bucket if bucket
    # is empty. Else updating bucket values.
    for num in arr:
        if num == max_val or num == min_val:
            continue

        # Finding index of bucket.
        index = int((num - min_val) // delta)

        max_bucket[index] = max(max_bucket[index], num)
        min_bucket[index] = min(min_bucket[index], num)

    # Finding maximum difference between maximum value
    # of previous bucket minus minimum of current bucket.
    prev_val = min_val
    max_gap = 0
    for i in range(len(arr) - 1):
        if min_bucket[i] == float('inf'):
            continue
        max_gap = max(max_gap, min_bucket[i] - prev_val)
        prev_val = max_bucket[i]
    max_gap = max(max_gap, max_val - prev_val)

    return max_gap

# Driver code
if __name__ == "__main__":
    arr = [1, 10, 5]
    print(max_sorted_adjacent_diff(arr))

Output
5


Time complexity: O(N) 
Auxiliary Space: O(N)

Article Tags :