Place k elements such that minimum distance is maximized

Given an array representing n positions along a straight line. Find k (where k <= n) elements from the array such that the maximum distance between any two (consecutive points among the k points) is maximized.

Examples :

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

Input  : arr[] = {1, 2, 7, 5, 11, 12}
             k = 3
Output : 5
Largest minimum distance = 5
3 elements arranged at positions 1, 7 and 12, 
resulting in a minimum distance of 5 (between
7 and 12)



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.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find largest minimum distance
// among k points.
#include <bits/stdc++.h>
  
using namespace std;
  
// 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;
}
  
// Driver code
int main()
{
    int arr[] = {1, 2, 8, 4, 9};
    int n = sizeof(arr)/sizeof(arr[0]);
    int k = 3;
    cout << largestMinDist(arr, n, k);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find largest 
// minimum distance among k points.
import java.util.Arrays;
  
class GFG 
{
// Returns true if it is possible to
// arrange k elements of arr[0..n-1]
// with minimum distance given as mid.
static boolean 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 false;
}
  
// Returns largest minimum distance for
// k elements in arr[0..n-1]. If elements 
// can't be placed, returns -1.
static int largestMinDist(int arr[], int n, 
                                     int k)
{
    // Sort the positions
    Arrays.sort(arr);
  
    // 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 if all elements can be
            // successfully placed
            res = Math.max(res, mid);
            left = mid + 1;
        }
  
        // If not possible to place k elements, 
        // search for lower distance
        else
            right = mid;
    }
  
    return res;
}
  
// driver code
public static void main (String[] args)
{
    int arr[] = {1, 2, 8, 4, 9};
    int n = arr.length;
    int k = 3;
    System.out.print(largestMinDist(arr, n, k));
}
}
  
// This code is contributed by Anant Agarwal.

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find largest 
// minimum distance among k points.
using System;
  
public class GFG {
      
    // Returns true if it is possible to
    // arrange k elements of arr[0..n-1]
    // with minimum distance given as mid.
    static 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 false;
    }
      
    // Returns largest minimum distance for
    // k elements in arr[0..n-1]. If elements 
    // can't be placed, returns -1.
    static int largestMinDist(int []arr, int n, 
                                          int k)
    {
          
        // Sort the positions
        Array.Sort(arr);
      
        // 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 if all elements
                // can be successfully placed
                res = Math.Max(res, mid);
                left = mid + 1;
            }
      
            // If not possible to place k
            // elements, search for lower
            // distance
            else
                right = mid;
        }
      
        return res;
    }
      
    // driver code
    public static void Main ()
    {
        int []arr = {1, 2, 8, 4, 9};
        int n = arr.Length;
        int k = 3;
          
        Console.WriteLine(
            largestMinDist(arr, n, k));
    }
}
  
// This code is contributed by Sam007.

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to find largest 
// minimum distance among k points.
  
// Returns true if it is possible 
// to arrange k elements of 
// arr[0..n-1] with minimum 
// distance given as mid.
function isFeasible($mid, $arr
                    $n, $k)
{
    // Place first element 
    // at arr[0] position
    $pos = $arr[0];
  
    // Initialize count of
    // elements placed.
    $elements = 1;
  
    // Try placing k elements 
    // with minimum distance mid.
    for ($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.
function largestMinDist($arr, $n, $k)
{
    // Sort the positions
    sort($arr);
  
    // Initialize result.
    $res = -1;
  
    // Consider the maximum
    // possible distance
    $left = $arr[0];
    $right = $arr[$n - 1];
  
    // Do binary search for
    // largest minimum distance
    while ($left < $right)
    {
        $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;
}
  
// Driver Code
$arr = array(1, 2, 8, 4, 9);
$n = sizeof($arr);
$k = 3;
echo largestMinDist($arr, $n, $k);
  
// This code is contributed by aj_36
?>

chevron_right



Output :

3

This article is contributed by Raghav Jajodia. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up

Improved By : Sam007, jit_t, sonamchawla