Given an array of N integers the task is to select K elements out of these N elements in such a way that the minimum difference between each of the K numbers is the Largest. Return the largest minimum difference after choosing any K elements.
Examples:
Input: N = 4, K = 3, arr = [2, 6, 2, 5]
Output: 1
Explanation: 3 elements out of 4 elements are to be selected with a minimum difference as large as possible. Selecting 2, 2, 5 will result in minimum difference as 0. Selecting 2, 5, 6 will result in minimum difference as 6-5=1
Input: N = 7, K = 4, arr = [1, 4, 9, 0, 2, 13, 3]
Output: 4
Explanation: Selecting 0, 4, 9, 13 will result in minimum difference of 4, which is the largest minimum difference possible
Naive Approach: Generate all the subsets of size K and find the minimum difference in all of them. Then return the maximum among the differences.
Efficient Approach: Given problem can be solved efficiently using binary search on answer technique. Below steps can be followed to solve the problem:
- Sort the array in ascending order
- Initialize minimum answer ans to 1
- Binary search is used on the range 1 to maximum element in array arr
- Variable dif is used to store the largest minimum difference at every iteration
- Helper function is used to check if selection of K elements is possible with minimum difference greater than dif calculated in previous iteration. If possible then true is returned or else false is returned.
- If above function returns:
- True then update ans to dif and left to dif + 1
- False then update right to dif – 1
Below is the implementation of the above binary search approach
C++
#include <bits/stdc++.h>
using namespace std;
bool isPossibleToSelect( int arr[], int N,
int dif, int K)
{
int count = 1;
int prev = arr[0];
for ( int i = 1; i < N; i++) {
if (arr[i] >= (prev + dif)) {
count++;
if (count == K)
return true ;
prev = arr[i];
}
}
return false ;
}
int binarySearch( int arr[], int left,
int right, int K, int N)
{
int ans = 1;
while (left <= right) {
int dif = left + (right - left) / 2;
if (isPossibleToSelect(arr, N,
dif, K)) {
ans = max(ans, dif);
left = dif + 1;
}
else
right = dif - 1;
}
return ans;
}
int main()
{
int N, K;
N = 7, K = 4;
int arr[] = { 1, 4, 9, 0, 2, 13, 3 };
sort(arr, arr + N);
cout << binarySearch(arr, 0, arr[N - 1], K, N)
<< "\n" ;
return 0;
}
|
Java
import java.io.*;
import java.util.Arrays;
class GFG{
static boolean isPossibleToSelect( int []arr, int N,
int dif, int K)
{
int count = 1 ;
int prev = arr[ 0 ];
for ( int i = 1 ; i < N; i++) {
if (arr[i] >= (prev + dif)) {
count++;
if (count == K)
return true ;
prev = arr[i];
}
}
return false ;
}
static int binarySearch( int []arr, int left,
int right, int K, int N)
{
int ans = 1 ;
while (left <= right) {
int dif = left + (right - left) / 2 ;
if (isPossibleToSelect(arr, N,
dif, K)) {
ans = Math.max(ans, dif);
left = dif + 1 ;
}
else
right = dif - 1 ;
}
return ans;
}
public static void main(String[] args)
{
int N, K;
N = 7 ;
K = 4 ;
int []arr = { 1 , 4 , 9 , 0 , 2 , 13 , 3 };
Arrays.sort(arr);
System.out.println(binarySearch(arr, 0 , arr[N - 1 ], K, N));
}
}
|
Python3
def isPossibleToSelect(arr, N,
dif, K):
count = 1
prev = arr[ 0 ]
for i in range ( 1 , N):
if (arr[i] > = (prev + dif)):
count + = 1
if (count = = K):
return True
prev = arr[i]
return False
def binarySearch(arr, left,
right, K, N):
ans = 1
while (left < = right):
dif = left + (right - left) / / 2
if (isPossibleToSelect(arr, N, dif, K)):
ans = max (ans, dif)
left = dif + 1
else :
right = dif - 1
return ans
if __name__ = = "__main__" :
N = 7
K = 4
arr = [ 1 , 4 , 9 , 0 , 2 , 13 , 3 ]
arr.sort()
print (binarySearch(arr, 0 , arr[N - 1 ], K, N)
)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static bool isPossibleToSelect( int []arr, int N,
int dif, int K)
{
int count = 1;
int prev = arr[0];
for ( int i = 1; i < N; i++) {
if (arr[i] >= (prev + dif)) {
count++;
if (count == K)
return true ;
prev = arr[i];
}
}
return false ;
}
static int binarySearch( int []arr, int left,
int right, int K, int N)
{
int ans = 1;
while (left <= right) {
int dif = left + (right - left) / 2;
if (isPossibleToSelect(arr, N,
dif, K)) {
ans = Math.Max(ans, dif);
left = dif + 1;
}
else
right = dif - 1;
}
return ans;
}
public static void Main()
{
int N, K;
N = 7;
K = 4;
int []arr = { 1, 4, 9, 0, 2, 13, 3 };
Array.Sort(arr);
Console.Write(binarySearch(arr, 0, arr[N - 1], K, N));
}
}
|
Javascript
<script>
function isPossibleToSelect(arr, N,
dif, K)
{
let count = 1;
let prev = arr[0];
for (let i = 1; i < N; i++) {
if (arr[i] >= (prev + dif)) {
count++;
if (count == K)
return true ;
prev = arr[i];
}
}
return false ;
}
function binarySearch(arr, left,
right, K, N) {
let ans = 1;
while (left <= right) {
let dif = left + Math.floor((right - left) / 2);
if (isPossibleToSelect(arr, N,
dif, K)) {
ans = Math.max(ans, dif);
left = dif + 1;
}
else
right = dif - 1;
}
return ans;
}
let N, K;
N = 7, K = 4;
let arr = [1, 4, 9, 0, 2, 13, 3];
arr.sort( function (a, b) { return a - b })
document.write(binarySearch(arr, 0, arr[N - 1], K, N)
+ '<br>' );
</script>
|
Time complexity: O(N * log N)
Space complexity: O(1)