Place k elements such that minimum distance is maximized - GeeksforGeeks
Given an array representing n positions along a straight line. Find k (where k <= n) elements from the array such that the minimum distance between any two (consecutive points among the k points) is maximized.
https://stackoverflow.com/questions/27971223/finding-largest-minimum-distance-among-k-objects-in-n-possible-distinct-position
Read full article from Place k elements such that minimum distance is maximized - GeeksforGeeks
Given an array representing n positions along a straight line. Find k (where k <= n) elements from the array such that the minimum distance between any two (consecutive points among the k points) is maximized.
Input : arr[] = {1, 2, 8, 4, 9} k = 3 Output : 3 Largest minimum distance = 3 3 elements arranged at positions 1, 4 and 8, Resulting in a minimum distance of 3
A Naive Solution is to consider all subsets of size 3 and find minimum distance for every subset. Finally return the largest of all minimum distances.
An Efficient Solution is based on Binary Search. We first sort the array. Now we know maximum possible value result is arr[n-1] – arr[0] (for k = 2). We do binary search for maximum result for given k. We start with middle of maximum possible result. If middle is a feasible solution, we search on right half of mid. Else we search is left half. To check feasibility, we place k elements under given mid distance.
https://stackoverflow.com/questions/27971223/finding-largest-minimum-distance-among-k-objects-in-n-possible-distinct-position
- Let's do a binary search over the answer.
- For a fixed answer
x
, we can check whether it is feasible or not using a simple linear greedy algorithm(pick the first element and then iterate over the rest of the array adding the current element if the distance between it and the last picked element is greater than or equal tox
). In the end, we just need to check that the number of picked elements is at leastk
.
The time complexity is
O(n * log MAX_A)
, where MAX_A
is the maximum element of the array.
Here is a pseudo code for this algorithm:
def isFeasible(positions, dist, k):
taken = 1
last = positions[0]
for i = 1 ... positions.size() - 1:
if positions[i] - last >= dist:
taken++
last = positions[i]
return taken >= k
def solve(positions, k):
low = 0 // definitely small enough
high = maxElement(positions) - minElement(positions) + 1 // definitely too big
while high - low > 1:
mid = (low + high) / 2
if isFeasible(positions, mid, k):
low = mid
else:
high = mid
return low
// Returns true if it is possible to arrange
// k elements of arr[0..n-1] with minimum distance
// given as mid.
bool
isFeasible(
int
mid,
int
arr[],
int
n,
int
k)
{
// Place first element at arr[0] position
int
pos = arr[0];
// Initialize count of elements placed.
int
elements = 1;
// Try placing k elements with minimum
// distance mid.
for
(
int
i=1; i<n; i++)
{
if
(arr[i] - pos >= mid)
{
// Place next element if its
// distance from the previously
// placed element is greater
// than current mid
pos = arr[i];
elements++;
// Return if all elements are placed
// successfully
if
(elements == k)
return
true
;
}
}
return
0;
}
// Returns largest minimum distance for k elements
// in arr[0..n-1]. If elements can't be placed,
// returns -1.
int
largestMinDist(
int
arr[],
int
n,
int
k)
{
// Sort the positions
sort(arr,arr+n);
// Initialize result.
int
res = -1;
// Consider the maximum possible distance
int
left = arr[0], right = arr[n-1];
// Do binary search for largest minimum distance
while
(left < right)
{
int
mid = (left + right)/2;
// If it is possible to place k elements
// with minimum distance mid, search for
// higher distance.
if
(isFeasible(mid, arr, n, k))
{
// Change value of variable max to mid iff
// all elements can be successfully placed
res = max(res, mid);
left = mid + 1;
}
// If not possible to place k elements, search
// for lower distance
else
right = mid;
}
return
res;
}