Given C magnets and an array arr[] representing N index positions where C ? N. The task is to place these magnets at these available indices in such a way that the distance between the two nearest magnets is as large as possible.
Examples:
Input: C = 4, arr[] = {1, 2, 5, 8, 10, 18}
Output: 4
We can place 4 magnets to positions 1, 5, 10, 18 so maximum distance is minimum of ( dist(1, 5), dist(5, 10), dist(10, 18) ) = dist(1, 5) = 4.
And it will be the maximum possible distance between two nearest magnets.
Input: C = 3, arr[] = {5, 7, 11, 20, 23}
Output: 6
We can place 3 magnets to positions 5, 11, 23 so answer will be minimum of ( dist(5, 11), dist(11, 23) ) = dist(5, 11) = 6.
Naive approach: Find all possible positions of magnets that is C(n, c) possible ways and find one that maximizes the distance between two magnets, where C(n, c) is selecting c objects from n given objects.
Efficient approach: Let mx be the maximum possible distance, therefore all x greater than 0 and less than mx will also allow placing magnets but for all y greater than mx, it will not be possible to place the magnets. Therefore we can use binary search to find the maximum possible distance.
Since our answer will always lie between 0 and the maximum index among the given N indices. Therefore apply binary search and find the middle value between the lowest and highest values say ‘mid’, make a function that will check if it is possible to place C magnets assuming ‘mid’ as the maximum possible distance.
Overall time complexity will be O(nlog(n)) since binary search will take O(log(n)) and O(n) for checking that if it is possible to place all C magnets.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool isPossible( int arr[], int n, int C, int mid)
{
int magnet = 1, currPosition = arr[0];
for ( int i = 1; i < n; i++) {
if (arr[i] - currPosition >= mid) {
magnet++;
currPosition = arr[i];
if (magnet == C)
return true ;
}
}
return false ;
}
int binarySearch( int n, int C, int arr[])
{
int lo, hi, mid, ans;
sort(arr, arr + n);
lo = 0;
hi = arr[n - 1];
ans = 0;
while (lo <= hi) {
mid = (lo + hi) / 2;
if (!isPossible(arr, n, C, mid))
hi = mid - 1;
else {
ans = max(ans, mid);
lo = mid + 1;
}
}
return ans;
}
int main()
{
int C = 4;
int arr[] = { 1, 2, 5, 8, 10, 18 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << binarySearch(n, C, arr) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static boolean isPossible( int []arr, int n,
int C, int mid)
{
int magnet = 1 , currPosition = arr[ 0 ];
for ( int i = 1 ; i < n; i++)
{
if (arr[i] - currPosition >= mid)
{
magnet++;
currPosition = arr[i];
if (magnet == C)
return true ;
}
}
return false ;
}
static int binarySearch( int n, int C, int []arr)
{
int lo, hi, mid, ans;
Arrays.sort(arr);
lo = 0 ;
hi = arr[n - 1 ];
ans = 0 ;
while (lo <= hi)
{
mid = (lo + hi) / 2 ;
if (!isPossible(arr, n, C, mid))
hi = mid - 1 ;
else
{
ans = Math.max(ans, mid);
lo = mid + 1 ;
}
}
return ans;
}
public static void main(String args[])
{
int C = 4 ;
int []arr = { 1 , 2 , 5 , 8 , 10 , 18 };
int n = arr.length;
System.out.println(binarySearch(n, C, arr));
}
}
|
Python3
def isPossible(arr, n, C, mid):
magnet = 1
currPosition = arr[ 0 ]
for i in range ( 1 , n):
if (arr[i] - currPosition > = mid):
magnet + = 1
currPosition = arr[i]
if (magnet = = C):
return True
return False
def binarySearch(n, C, arr):
arr.sort(reverse = False )
lo = 0
hi = arr[n - 1 ]
ans = 0
while (lo < = hi):
mid = int ((lo + hi) / 2 )
if (isPossible(arr, n, C, mid) = = False ):
hi = mid - 1
else :
ans = max (ans, mid)
lo = mid + 1
return ans
if __name__ = = '__main__' :
C = 4
arr = [ 1 , 2 , 5 , 8 , 10 , 18 ]
n = len (arr)
print (binarySearch(n, C, arr))
|
C#
using System;
class GFG
{
static bool isPossible( int []arr, int n,
int C, int mid)
{
int magnet = 1, currPosition = arr[0];
for ( int i = 1; i < n; i++)
{
if (arr[i] - currPosition >= mid)
{
magnet++;
currPosition = arr[i];
if (magnet == C)
return true ;
}
}
return false ;
}
static int binarySearch( int n, int C, int []arr)
{
int lo, hi, mid, ans;
Array.Sort(arr);
lo = 0;
hi = arr[n - 1];
ans = 0;
while (lo <= hi)
{
mid = (lo + hi) / 2;
if (!isPossible(arr, n, C, mid))
hi = mid - 1;
else
{
ans = Math.Max(ans, mid);
lo = mid + 1;
}
}
return ans;
}
static void Main()
{
int C = 4;
int []arr = { 1, 2, 5, 8, 10, 18 };
int n = arr.Length;
Console.WriteLine(binarySearch(n, C, arr));
}
}
|
PHP
<?php
function isPossible( $arr , $n , $C , $mid )
{
$magnet = 1; $currPosition = $arr [0];
for ( $i = 1; $i < $n ; $i ++)
{
if ( $arr [ $i ] - $currPosition >= $mid )
{
$magnet ++;
$currPosition = $arr [ $i ];
if ( $magnet == $C )
return true;
}
}
return false;
}
function binarySearch( $n , $C , $arr )
{
sort( $arr , 0);
$lo = 0;
$hi = $arr [ $n - 1];
$ans = 0;
while ( $lo <= $hi )
{
$mid = ( $lo + $hi ) / 2;
if (!isPossible( $arr , $n , $C , $mid ))
$hi = $mid - 1;
else
{
$ans = max( $ans , $mid );
$lo = $mid + 1;
}
}
return $ans ;
}
$C = 4;
$arr = array (1, 2, 5, 8, 10, 18);
$n = sizeof( $arr );
echo binarySearch( $n , $C , $arr ) . "\n" ;
?>
|
Javascript
<script>
function isPossible(arr, n, C, mid)
{
let magnet = 1; currPosition = arr[0];
for (let i = 1; i < n; i++)
{
if (arr[i] - currPosition >= mid)
{
magnet++;
currPosition = arr[i];
if (magnet == C)
return true ;
}
}
return false ;
}
function binarySearch(n, C, arr)
{
arr.sort((a, b) => a - b);
let lo = 0;
let hi = arr[n - 1];
let ans = 0;
while (lo <= hi)
{
mid = Math.floor((lo + hi) / 2);
if (!isPossible(arr, n, C, mid))
hi = mid - 1;
else
{
ans = Math.max(ans, mid);
lo = mid + 1;
}
}
return ans;
}
let C = 4;
let arr = new Array(1, 2, 5, 8, 10, 18);
let n = arr.length;
document.write(binarySearch(n, C, arr) + "<br>" );
</script>
|
Time Complexity: O(n * log(n))
Auxiliary Space: O(1)