Minimize the maximum difference between adjacent elements in an array
Last Updated :
04 Jul, 2022
Given a non-decreasing array arr[] and an integer K, the task is to remove K elements from the array such that maximum difference between adjacent element is minimum.
Note: K < N – 2
Examples:
Input: arr[] = {3, 7, 8, 10, 14}, K = 2
Output: 2
Explanation:
After removing elements A[0] and A[4],
The maximum difference between adjacent elements is minimum.
After removing elements, the remaining array is [7, 8, 10]
Input: arr[] = [12, 16, 22, 31, 31, 38], K = 3
Output: 6
Explanation:
After removing elements A[3], A[4] and A[5],
The maximum difference between adjacent elements is minimum.
After removing elements, the remaining array is [12, 16, 22]
Method 1: Brute Force The idea is to generate subsets of the array of size N – K and also compute the maximum difference of the adjacent elements in each subsequence. Finally, find the minimum of such maximum differences.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minimumAdjacentDifference(vector< int > a,
int n, int k)
{
int minDiff = INT_MAX;
for ( int i = 0; i < (1 << n); i++) {
int cnt = __builtin_popcount(i);
if (cnt == n - k) {
vector< int > temp;
for ( int j = 0; j < n; j++) {
if ((i & (1 << j)) != 0)
temp.push_back(a[j]);
}
int maxDiff = INT_MIN;
for ( int j = 0; j < temp.size() - 1; j++) {
maxDiff = max(maxDiff,
temp[j + 1] - temp[j]);
}
minDiff = min(minDiff, maxDiff);
}
}
return minDiff;
}
int main()
{
int n = 5;
int k = 2;
vector< int > a= { 3, 7, 8, 10, 14 };
cout << minimumAdjacentDifference(a, n, k);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int minimumAdjacentDifference( int a[],
int n, int k)
{
int minDiff = Integer.MAX_VALUE;
for ( int i = 0 ; i < ( 1 << n); i++) {
int cnt = Integer.bitCount(i);
if (cnt == n - k) {
Vector<Integer> temp = new Vector<Integer>();
for ( int j = 0 ; j < n; j++) {
if ((i & ( 1 << j)) != 0 )
temp.add(a[j]);
}
int maxDiff = Integer.MIN_VALUE;
for ( int j = 0 ; j < temp.size() - 1 ; j++) {
maxDiff = Math.max(maxDiff,
temp.get(j + 1 ) - temp.get(j));
}
minDiff = Math.min(minDiff, maxDiff);
}
}
return minDiff;
}
public static void main(String args[])
{
int n = 5 ;
int k = 2 ;
int a[] = { 3 , 7 , 8 , 10 , 14 };
System.out.println(minimumAdjacentDifference(a, n, k));
}
}
|
Python3
import sys
INT_MAX = sys.maxsize;
INT_MIN = - (sys.maxsize - 1 )
def minimumAdjacentDifference(a, n, k) :
minDiff = INT_MAX;
for i in range ( 1 <<n) :
cnt = bin (i).count( '1' );
if (cnt = = n - k) :
temp = [];
for j in range (n) :
if ((i & ( 1 << j)) ! = 0 ) :
temp.append(a[j]);
maxDiff = INT_MIN;
for j in range ( len (temp) - 1 ) :
maxDiff = max (maxDiff, temp[j + 1 ] - temp[j]);
minDiff = min (minDiff, maxDiff);
return minDiff;
if __name__ = = "__main__" :
n = 5 ;
k = 2 ;
a = [ 3 , 7 , 8 , 10 , 14 ];
print (minimumAdjacentDifference(a, n, k));
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int minimumAdjacentDifference( int []a,
int n, int k)
{
int minDiff = int .MaxValue;
for ( int i = 0; i < (1 << n); i++) {
int cnt = countSetBits(i);
if (cnt == n - k) {
List< int > temp = new List< int >();
for ( int j = 0; j < n; j++) {
if ((i & (1 << j)) != 0)
temp.Add(a[j]);
}
int maxDiff = int .MinValue;
for ( int j = 0; j < temp.Count - 1; j++) {
maxDiff = Math.Max(maxDiff,
temp[j + 1] - temp[j]);
}
minDiff = Math.Min(minDiff, maxDiff);
}
}
return minDiff;
}
static int countSetBits( int x)
{
int setBits = 0;
while (x != 0) {
x = x & (x - 1);
setBits++;
}
return setBits;
}
public static void Main(String []args)
{
int n = 5;
int k = 2;
int []a = { 3, 7, 8, 10, 14 };
Console.WriteLine(minimumAdjacentDifference(a, n, k));
}
}
|
Javascript
<script>
function countSetBits(x)
{
let setBits = 0;
while (x != 0)
{
x = x & (x - 1);
setBits++;
}
return setBits;
}
function minimumAdjacentDifference(a, n, k)
{
let minDiff = Number.MAX_VALUE;
for (let i = 0; i < (1 << n); i++)
{
let cnt = countSetBits(i);
if (cnt == n - k)
{
let temp = [];
for (let j = 0; j < n; j++)
{
if ((i & (1 << j)) != 0)
temp.push(a[j]);
}
let maxDiff = Number.MIN_VALUE;
for (let j = 0; j < temp.length - 1; j++)
{
maxDiff = Math.max(
maxDiff, temp[j + 1] - temp[j]);
}
minDiff = Math.min(minDiff, maxDiff);
}
}
return minDiff;
}
let n = 5;
let k = 2;
let a = [ 3, 7, 8, 10, 14 ];
document.write(minimumAdjacentDifference(a, n, k));
</script>
|
Time Complexity: O(2N * N)
Auxiliary Space: O(N)
Method 2: Optimal approach
- On careful observation, it can be noted that, if removal of element is done from somewhere in between the array (i.e not the end elements), then the maximum difference of remaining elements can only increase or remain the same.
For Example:
Let the given array be {1, 5, 6},
If we remove the element 5(not the end element),
then the maximum difference will always increase.
Therefore, It is always better to remove end elements.
- This means that the resulting array after removing K elements will be a subarray of the original array of size N – K.
- Hence, We can iterate over all the subarrays of size N – K and for each subarray find the maximum difference between adjacent elements. Finally, find the minimum of all the maximum differences of adjacent elements.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minimumAdjacentDifference(vector< int > a,
int n, int k)
{
int minDiff = INT_MAX;
for ( int i = 0; i <= k; i++) {
int maxDiff = INT_MIN;
for ( int j = 0; j < n - k - 1; j++) {
for ( int p = i; p <= i + j; p++) {
maxDiff = max(maxDiff,
a[p + 1] - a[p]);
}
}
minDiff = min(minDiff, maxDiff);
}
return minDiff;
}
int main()
{
int n = 5;
int k = 2;
vector< int > a = { 3, 7, 8, 10, 14 };
cout << minimumAdjacentDifference(a, n, k);
return 0;
}
|
Java
class GFG {
static int minimumAdjacentDifference( int a[],
int n, int k)
{
int minDiff = Integer.MAX_VALUE;
for ( int i = 0 ; i <= k; i++) {
int maxDiff = Integer.MIN_VALUE;
for ( int j = 0 ; j < n - k - 1 ; j++) {
for ( int p = i; p <= i + j; p++) {
maxDiff = Math.max(maxDiff,
a[p + 1 ] - a[p]);
}
}
minDiff = Math.min(minDiff, maxDiff);
}
return minDiff;
}
public static void main (String[] args)
{
int n = 5 ;
int k = 2 ;
int []a = { 3 , 7 , 8 , 10 , 14 };
System.out.println(minimumAdjacentDifference(a, n, k));
}
}
|
Python3
import sys
INT_MAX = sys.maxsize;
INT_MIN = - (sys.maxsize - 1 );
def minimumAdjacentDifference(a, n, k) :
minDiff = INT_MAX;
for i in range (k + 1 ) :
maxDiff = INT_MIN;
for j in range ( n - k - 1 ) :
for p in range (i, i + j + 1 ) :
maxDiff = max (maxDiff, a[p + 1 ] - a[p]);
minDiff = min (minDiff, maxDiff);
return minDiff;
if __name__ = = "__main__" :
n = 5 ;
k = 2 ;
a = [ 3 , 7 , 8 , 10 , 14 ];
print (minimumAdjacentDifference(a, n, k));
|
C#
using System;
class GFG {
static int minimumAdjacentDifference( int []a,
int n, int k)
{
int minDiff = int .MaxValue;
for ( int i = 0; i <= k; i++) {
int maxDiff = int .MinValue;
for ( int j = 0; j < n - k - 1; j++) {
for ( int p = i; p <= i + j; p++) {
maxDiff = Math.Max(maxDiff,
a[p + 1] - a[p]);
}
}
minDiff = Math.Min(minDiff, maxDiff);
}
return minDiff;
}
public static void Main ( string [] args)
{
int n = 5;
int k = 2;
int []a = { 3, 7, 8, 10, 14 };
Console.WriteLine(minimumAdjacentDifference(a, n, k));
}
}
|
Javascript
<script>
function minimumAdjacentDifference(a,n,k)
{
let minDiff = Number.MAX_VALUE;
for (let i = 0; i <= k; i++) {
let maxDiff = Number.MIN_VALUE;
for (let j = 0; j < n - k - 1; j++) {
for (let p = i; p <= i + j; p++) {
maxDiff = Math.max(maxDiff,
a[p + 1] - a[p]);
}
}
minDiff = Math.min(minDiff, maxDiff);
}
return minDiff;
}
let n = 5;
let k = 2;
let a = [ 3, 7, 8, 10, 14 ];
document.write(minimumAdjacentDifference(a, n, k));
</script>
|
Time complexity: O(N * K2)
Auxiliary Space: O(1)
Method 3: Efficient Approach
- Using the idea from Method 2, we need to find the minimum of maximum adjacent element differences of all subarrays of size N – K. If we create a difference array, i.e. an array of differences of adjacent elements of the initial array, then all we need to do is find the minimum element of the maximum of all subarrays of size N – K – 1 of this difference array (as this maximum will represent the maximum adjacent difference of original array’s subarray of size N – K).
- For performing this operation we can use the sliding window method using the double-ended queue. Refer to Sliding Window Maximum (Maximum of all subarrays of size K) for this approach.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findKMin(vector< int > arr, int n, int k)
{
deque< int > Qi(k);
int i;
for (i = 0; i < k; ++i) {
while ((!Qi.empty()) &&
arr[i] >= arr[Qi.back()])
Qi.pop_back();
Qi.push_back(i);
}
int minDiff = INT_MAX;
for (; i < n; ++i) {
minDiff = min(minDiff, arr[Qi.front()]);
while ((!Qi.empty()) && Qi.front() <= i - k)
Qi.pop_front();
while ((!Qi.empty()) &&
arr[i] >= arr[Qi.back()])
Qi.pop_back();
Qi.push_back(i);
}
minDiff = min(minDiff, arr[Qi.front()]);
return minDiff;
}
int minimumAdjacentDifference(vector< int > a,
int n, int k)
{
vector< int > diff(n-1);
for ( int i = 0; i < n - 1; i++) {
diff[i] = a[i + 1] - a[i];
}
int answer = findKMin(diff,
n - 1, n - k - 1);
return answer;
}
int main()
{
int n = 5;
int k = 2;
vector< int > a= { 3, 7, 8, 10, 14 };
cout << minimumAdjacentDifference(a, n, k);
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
class GFG{
static int findKMin( int arr[], int n, int k)
{
Deque<Integer> Qi = new LinkedList<>();
int i;
for (i = 0 ; i < k; ++i)
{
while ((!Qi.isEmpty()) &&
arr[i] >= arr[Qi.peekLast()])
Qi.pollLast();
Qi.addLast(i);
}
int minDiff = Integer.MAX_VALUE;
for (; i < n; ++i)
{
minDiff = Math.min(minDiff,
arr[Qi.peekFirst()]);
while ((!Qi.isEmpty()) &&
Qi.peekFirst() <= i - k)
Qi.pollFirst();
while ((!Qi.isEmpty()) &&
arr[i] >= arr[Qi.peekLast()])
Qi.pollLast();
Qi.addLast(i);
}
minDiff = Math.min(minDiff,
arr[Qi.peekFirst()]);
return minDiff;
}
static int minimumAdjacentDifference( int a[],
int n, int k)
{
int [] diff = new int [n - 1 ];
for ( int i = 0 ; i < n - 1 ; i++)
{
diff[i] = a[i + 1 ] - a[i];
}
int answer = findKMin(diff,
n - 1 ,
n - k - 1 );
return answer;
}
public static void main(String[] args)
{
int n = 5 ;
int k = 2 ;
int a[] = { 3 , 7 , 8 , 10 , 14 };
System.out.println(minimumAdjacentDifference(a, n, k));
}
}
|
Python3
import sys
def findKMin(arr, n, k):
Qi = []
i = 0
for j in range (k):
while (( len (Qi) ! = 0 ) and
arr[i] > = arr[Qi[ - 1 ]]):
Qi.pop()
Qi.append(i)
i + = 1
minDiff = sys.maxsize;
for j in range (i, n):
minDiff = min (minDiff, arr[Qi[ 0 ]])
while (( len (Qi) ! = 0 ) and
Qi[ 0 ] < = i - k):
Qi.pop( 0 )
while (( len (Qi) ! = 0 ) and
arr[i] > = arr[Qi[ - 1 ]]):
Qi.pop()
Qi.append(i)
i + = 1
minDiff = min (minDiff, arr[Qi[ 0 ]])
return minDiff
def minimumAdjacentDifference(a, n, k):
diff = [ 0 for i in range (n - 1 )]
for i in range (n - 1 ):
diff[i] = a[i + 1 ] - a[i]
answer = findKMin(diff, n - 1 ,
n - k - 1 )
return answer
if __name__ = = "__main__" :
n = 5
k = 2
a = [ 3 , 7 , 8 , 10 , 14 ]
print (minimumAdjacentDifference(a, n, k))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int findKMin(List< int > arr, int n, int k)
{
List< int > Qi = new List< int >();
int i = 0;
for ( int j = 0; j < k; j++)
{
while ((Qi.Count != 0)
&& (arr[i] >= arr[Qi[Qi.Count - 1]]))
Qi.RemoveAt(Qi.Count
- 1);
Qi.Add(i);
i += 1;
}
int minDiff = Int32.MaxValue;
for ( int j = i; j < n; j++) {
minDiff = Math.Min(minDiff, arr[Qi[0]]);
while ((Qi.Count != 0) && (Qi[0] <= i - k))
Qi.RemoveAt(0);
while ((Qi.Count != 0)
&& (arr[i] >= arr[Qi[Qi.Count - 1]]))
Qi.RemoveAt(Qi.Count - 1);
Qi.Add(i);
i += 1;
}
minDiff = Math.Min(minDiff, arr[Qi[0]]);
return minDiff;
}
static int minimumAdjacentDifference( int [] a, int n,
int k)
{
List< int > diff = new List< int >();
for ( var i = 0; i < n - 1; i++)
diff.Add(a[i + 1] - a[i]);
var answer = findKMin(diff, n - 1, n - k - 1);
return answer;
}
public static void Main( string [] args)
{
int n = 5;
int k = 2;
int [] a = { 3, 7, 8, 10, 14 };
Console.Write(minimumAdjacentDifference(a, n, k));
}
}
|
Javascript
<script>
function findKMin(arr, n, k)
{
var Qi = [];
var i = 0;
for ( var j = 0; j < k; j++)
{
while ((Qi.length != 0) && (arr[i] >= arr[Qi[-1]]))
Qi.pop();
Qi.push(i);
i += 1;
}
var minDiff = Number.MAX_SAFE_INTEGER;
for ( var j = i; j < n; j++)
{
minDiff = Math.min(minDiff, arr[Qi[0]]);
while ((Qi.length != 0) && (Qi[0] <= i - k))
Qi.shift();
while ((Qi.length != 0) && (arr[i] >= arr[Qi[Qi.length -1]]))
Qi.pop();
Qi.push(i);
i += 1;
}
minDiff = Math.min(minDiff, arr[Qi[0]]);
return minDiff;
}
function minimumAdjacentDifference(a, n, k)
{
var diff = [];
for ( var i = 0; i < n - 1; i++)
diff.push(a[i + 1] - a[i]);
var answer = findKMin(diff, n - 1, n - k - 1);
return answer;
}
let n = 5;
let k = 2;
let a = [ 3, 7, 8, 10, 14 ];
document.write(minimumAdjacentDifference(a, n, k));
</script>
|
Time complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...