📌  相关文章
📜  放置k个元素,以使最小距离最大化

📅  最后修改于: 2021-04-24 19:12:08             🧑  作者: Mango

给定一个沿直线表示n个位置的数组。从数组中找到k个(其中k <= n)个元素,以使任意两个(k个点中的连续点)之间的最小距离最大。

例子 :

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)

幼稚的解决方案是考虑大小为3的所有子集,并为每个子集找到最小距离。最后返回所有最小距离中的最大距离。

高效的解决方案基于二进制搜索。我们首先对数组进行排序。现在我们知道最大可能值结果是arr [n-1] – arr [0](对于k = 2)。对于给定的k,我们对最大结果进行二进制搜索。我们从最大可能结果的中间开始。如果中线是可行的解决方案,我们将在中线的右半部分进行搜索。否则,我们搜索将剩下一半。为了检查可行性,我们将k个元素放置在给定的中间距离下。

C++
// C++ program to find largest minimum distance
// among k points.
#include 
 
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
    //here we are using right value as higest distance difference,
      //so we remove some extra checks
    int left = 1, right = arr[n - 1] - arr[0];
 
    // left is initialized with 1 and not with arr[0]
    // because, minimum distance between each element
    // can be one and not arr[0]. consider this example:
    // arr[] = {9,12} and you have to place 2 element
    // then left = arr[0] will force the function to
    // look the answer between range arr[0] to arr[n-1],
    // i.e 9 to 12, but the answer is 3 so It is required
    // that you initialize the left with 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;
}


Java
// 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] - arr[0];
 
        // left is initialized with 1 and not with arr[0]
        // because, minimum distance between each element
        // can be one and not arr[0]. consider this example:
        // arr[] = {9,12} and you have to place 2 element
        // then left = arr[0] will force the function to
        // look the answer between range arr[0] to arr[n-1],
        // i.e 9 to 12, but the answer is 3 so It is
        // required that you initialize the left with 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.


Python3
# Python 3 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.
 
 
def 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 in range(1, n, 1):
        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 += 1
 
            # 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.
 
 
def largestMinDist(arr, n, k):
 
    # Sort the positions
    arr.sort(reverse=False)
 
    # Initialize result.
    res = -1
 
    # Consider the maximum possible distance
    left = arr[0]
    right = arr[n - 1] - arr[0]
 
    # left is initialized with 1 and not with arr[0]
    # because, minimum distance between each element
    # can be one and not arr[0]. consider this example:
    # arr[] = {9,12} and you have to place 2 element
    # then left = arr[0] will force the function to
    # look the answer between range arr[0] to arr[n-1],
    # i.e 9 to 12, but the answer is 3 so It is required
    # that you initialize the left with 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
if __name__ == '__main__':
    arr = [1, 2, 8, 4, 9]
    n = len(arr)
    k = 3
    print(largestMinDist(arr, n, k))
 
# This code is contributed by
# Sanjit_prasad


C#
// 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] - arr[0];
 
        // left is initialized with 1 and not with arr[0]
        // because, minimum distance between each element
        // can be one and not arr[0]. consider this example:
        // arr[] = {9,12} and you have to place 2 element
        // then left = arr[0] will force the function to
        // look the answer between range arr[0] to arr[n-1],
        // i.e 9 to 12, but the answer is 3 so It is
        // required that you initialize the left with 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.


PHP
= $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] -$arr[0];
   
    // left is initialized with 1 and not with arr[0]
    // because, minimum distance between each element
    // can be one and not arr[0]. consider this example:
    // arr[] = {9,12} and you have to place 2 element
    // then left = arr[0] will force the function to
    // look the answer between range arr[0] to arr[n-1],
    // i.e 9 to 12, but the answer is 3 so It is required
    // that you initialize the left with 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
?>


输出 :

3