Minimize the Maximum difference between Adjacent Elements in an Array


In this problem, we will minimize the maximum difference between adjacent elements by removing any M elements from the array.

The naïve approach to solving the problem is to pick total N − M array elements and check which set contains the minimum or maximum adjacent difference. The optimized approach uses the queue data structure to solve the problem.

Problem statement : We have given an sorted array of numbers in sorted order. We have also given M. We need to remove M elements from the array such that we can minimize the maximum difference between the adjacent array elements.

Sample examples

Input

nums = {5, 9, 12, 13, 14, 19}, M = 3

Output

 1

Explanation : We can remove the 5, 9, and 19 from the array. So, the minimum of maximum adjacent differences between adjacent array elements is 1.

Input

nums = {8, 9, 12, 13, 17}, M = 2

Output

3

Explanation : We can remove 8 and 17 to minimize the maximum adjacent difference.

Input

nums = {8, 9, 10, 11, 12, 13}, K = 1

Output

1

Explanation : We can remove any 3 elements, as adjacent differences between all elements are the same.

Approach 1

Here, we will use the brute force approach to solve the problem. From the array, we can create 2N sets. After that, we check the maximum adjacent difference for each set of N − K elements and take the minimum of them as an answer.

Algorithm

Step 1 − Initialize the ‘min_diff’ value with the maximum integer value.

Step 2 − Use the for loop to make the 2N iterations.

Step 3 − Next, find the number of set bits in the ‘p’ (current index) using the __builtin_popcount() method and store it in the ‘cnt’ method.

Step 4 − If the ‘cnt’ equals N − K, follow the steps below.

Step 4.1 − Initialize the ‘tmp’ list to store array elements.

Step 4.2 − Start traversing the array. If the current bit is set−bit in the index ‘p’, insert the element into the ‘tmp’ list.

Step 4.3 − Initialize the max_diff with the minimum integer value.

Step 4.4 − Traverse the array elements and find the maximum adjacent difference.

Step 4.5 − After that, update the min_diff if it is greater than the max_diff.

Step 5 − Return the min_diff value.

Example

#include <bits/stdc++.h>
using namespace std;

int minimumDiff(vector<int> nums, int len, int M) {
    // Minimum difference
    int min_diff = INT_MAX;
    // Traverse for 2^N subsets
    for (int p = 0; p < (1 << len); p++) {
        // Number of array elements to be considered in the given set. It gives the number of 1 in the binary string
        int cnt = __builtin_popcount(p);
        // When len - M elements are left in the set
        if (cnt == len - M) {
            // temporary array
            vector<int> tmp;
            for (int q = 0; q < len; q++) {
                if ((p & (1 << q)) != 0)
                    tmp.push_back(nums[q]);
            }
            // To store the maximum difference of adjacent elements
            int max_diff = INT_MIN;
            for (int q = 0; q < tmp.size() - 1; q++) {
                max_diff = max(max_diff,  tmp[q + 1] - tmp[q]);
            }
            min_diff = min(min_diff, max_diff);
        }
    }
    return min_diff;
}

int main() {
    int M = 3;
    vector<int> nums = {5, 9, 12, 13, 14, 19};
    int len = nums.size();
    cout << "The minimum of maximum difference between adjacent elements is " << minimumDiff(nums, len, M);
    return 0;
}

Output

The minimum of maximum difference between adjacent elements is 1

Time complexity − O(N*2N), where O(N) is to traverse the array and O(2N) is for checking each subset of the array.

Space complexity − O(N − M) to store the array elements.

Approach 2

We can observe that removing an array element from the middle of the array always increases the difference between the array element as the array is sorted in increasing order. So, we always need to remove array elements from both ends of the array.

For example, the array is [2, 5, 7, 9, 10]. If we remove 9, it increases the difference between 7 and 10. So, removing array elements from both ends is a good idea.

To solve the problem, we will store the difference of adjacent elements in the array. After that, we will traverse each subarray of size N − K and take a minimum of maximum adjacent difference among all subarrays using the sliding window technique.

Algorithm

Step 1 − Traverse the array and store the difference between the next and current element in the nums_diff[p].

Step 2 − Execute the findMinimum() function to find the minimum difference in each subarray.

Step 3 − In the findMinimum() function, create a deque of size k to store the indexes of the array elements.

Step 4 − Handle the first window using the loop. If the queue is not empty, and the element at the last index of the queue is greater than the current element, remove the element from the queue. Also, use a while loop to remove all greater elements than the current element.

Step 5 − Insert the current element into the queue.

Step 6 − Now, we need to handle other windows. So, Initialize the min_diff with the maximum integer value and start traversing the other window.

Step 7 − Update the min_diff variable’s value if the element at the ind_que.front() index is smaller than the min_diff.

Step 8− Use the loop, and remove the indexes of the previous window from the queue.

Step 9 − Remove the indexes of the smaller elements than the current element, and insert the current element into the queue.

Step 10 − Handle the min_diff value for the last window and return it from the function.

Example

#include <bits/stdc++.h>
using namespace std;

int findMinium(vector<int> arr, int n, int k) {
    // Deque to store array indexes
    deque<int> ind_que(k);
    int p;
    // Handle the first window
    for (p = 0; p < k; ++p) {
        // Remove smaller elements from the back of queue
        while ((!ind_que.empty()) && arr[p] >= arr[ind_que.back()])
            ind_que.pop_back(); // Remove last element
        // Add curent index to queue
        ind_que.push_back(p);
    }
    int min_diff = INT_MAX;
    // Handle other windows
    for (; p < n; ++p) {
        // The first element is largest in deque
        min_diff = min(min_diff, arr[ind_que.front()]);
        // Update the current window
        while ((!ind_que.empty()) && ind_que.front() <= p - k)
            ind_que.pop_front();
        // Remove smaller elements than current element
        while ((!ind_que.empty()) && arr[p] >= arr[ind_que.back()])
            ind_que.pop_back();
        // Push current element
        ind_que.push_back(p);
    }
    // Handle the last window
    min_diff = min(min_diff, arr[ind_que.front()]);
    return min_diff;
}
int minimumDiff(vector<int> nums, int len, int M) {
    // Difference array
    vector<int> nums_diff(len - 1);
    for (int p = 0; p < len - 1; p++) {
        nums_diff[p] = nums[p + 1] - nums[p];
    }
    return findMinium(nums_diff, len - 1, len - M - 1);
}
int main() {
    int M = 2;
    vector<int> nums = {8, 9, 12, 13, 17};
    int len = nums.size();
    cout << "The minimum of maximum difference between adjacent elements is " << minimumDiff(nums, len, M);
    return 0;
}

Output

The minimum of maximum difference between adjacent elements is 3

Time complexity − O(N)

Space complexity − O(N) to store difference into the queue.

We used the deque data structure as we can perform insertion and deletion operations from both ends in the deque. Programmers may try to solve the problem using different data structures like arrays.

Updated on: 22-Jul-2023

311 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements