📌  相关文章
📜  从数组中选取点,以使最小距离最大化

📅  最后修改于: 2021-04-28 14:24:10             🧑  作者: Mango

给定C个磁体和代表N个索引位置的数组arr [] ,其中C≤N 。任务是将这些磁铁放置在这些可用的索引处,以使两个最近的磁铁之间的距离尽可能大。

例子:

天真的方法:找到所有可能的C(n,c)种可能的磁体位置,并找到一种最大化两个磁体之间距离的磁体,其中C(n,c)从n个给定对象中选择c个对象。

高效方法:将mx设为最大可能距离,因此所有大于0且小于mx的x都将允许放置磁体,但是对于所有大于mx的y,将无法放置磁体。因此,我们可以使用二进制搜索来找到最大可能的距离。
由于我们的答案将始终位于0到给定N个索引中的最大索引之间。因此,应用二进制搜索并找到介于最低值和最高值之间的中间值,例如“ mid”,使该函数检查是否有可能以“ mid”为最大可能距离放置C磁体。
总时间复杂度将为O(nlog(n)),因为二进制搜索将使用O(log(n))和O(n)来检查是否可以放置所有C磁体。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
// Function to check if it is possible
// to place C magnets assuming mid as
// maximum possible distance
bool isPossible(int arr[], int n, int C, int mid)
{
    // Variable magnet will store count of magnets
    // that got placed and currPosition will store
    // the position of last placed magnet
    int magnet = 1, currPosition = arr[0];
  
    for (int i = 1; i < n; i++) {
  
        // If difference between current index and
        // last placed index is greater than or equal to mid
        // it will allow placing magnet to this index
        if (arr[i] - currPosition >= mid) {
  
            magnet++;
  
            // Now this index will become
            // last placed index
            currPosition = arr[i];
  
            // If count of magnets placed becomes C
            if (magnet == C)
                return true;
        }
    }
  
    // If count of placed magnet is
    // less than C then return false
    return false;
}
  
// Function for modified binary search
int binarySearch(int n, int C, int arr[])
{
    int lo, hi, mid, ans;
  
    // Sort the indices in ascending order
    sort(arr, arr + n);
  
    // Minimum possible distance
    lo = 0;
  
    // Maximum possible distance
    hi = arr[n - 1];
  
    ans = 0;
  
    // Run the loop until lo becomes
    // greater than hi
    while (lo <= hi) {
  
        mid = (lo + hi) / 2;
  
        // If not possibble, decrease value of hi
        if (!isPossible(arr, n, C, mid))
            hi = mid - 1;
        else {
  
            // Update the answer
            ans = max(ans, mid);
            lo = mid + 1;
        }
    }
  
    // Return maximum possible distance
    return ans;
}
  
// Driver code
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
// Java implementation of the approach
import java.util.*;
  
class GFG
{
  
// Function to check if it is possible
// to place C magnets assuming mid as
// maximum possible distance
static boolean isPossible(int []arr, int n, 
                        int C, int mid)
{
    // Variable magnet will store count of magnets
    // that got placed and currPosition will store
    // the position of last placed magnet
    int magnet = 1, currPosition = arr[0];
  
    for (int i = 1; i < n; i++) 
    {
  
        // If difference between current index and
        // last placed index is greater than or equal to mid
        // it will allow placing magnet to this index
        if (arr[i] - currPosition >= mid)
        {
  
            magnet++;
  
            // Now this index will become
            // last placed index
            currPosition = arr[i];
  
            // If count of magnets placed becomes C
            if (magnet == C)
                return true;
        }
    }
  
    // If count of placed magnet is
    // less than C then return false
    return false;
}
  
// Function for modified binary search
static int binarySearch(int n, int C, int []arr)
{
    int lo, hi, mid, ans;
  
    // Sort the indices in ascending order
    Arrays.sort(arr);
  
    // Minimum possible distance
    lo = 0;
  
    // Maximum possible distance
    hi = arr[n - 1];
  
    ans = 0;
  
    // Run the loop until lo becomes
    // greater than hi
    while (lo <= hi) 
    {
  
        mid = (lo + hi) / 2;
  
        // If not possibble, decrease value of hi
        if (!isPossible(arr, n, C, mid))
            hi = mid - 1;
        else
        {
  
            // Update the answer
            ans = Math.max(ans, mid);
            lo = mid + 1;
        }
    }
  
    // Return maximum possible distance
    return ans;
}
  
// Driver code
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));
}
}
  
// This code is contributed by Akanksha Rai


Python3
# Python 3 implementation of the approach
  
# Function to check if it is possible
# to place C magnets assuming mid as
# maximum possible distance
def isPossible(arr, n, C, mid):
      
    # Variable magnet will store count of 
    # magnets that got placed and 
    # currPosition will store the position 
    # of last placed magnet
    magnet = 1
    currPosition = arr[0]
  
    for i in range(1, n):
          
        # If difference between current index 
        # and last placed index is greater than 
        # or equal to mid it will allow placing 
        # magnet to this index
        if (arr[i] - currPosition >= mid):
            magnet += 1
  
            # Now this index will become
            # last placed index
            currPosition = arr[i]
  
            # If count of magnets placed becomes C
            if (magnet == C):
                return True
  
    # If count of placed magnet is
    # less than C then return false
    return False
  
# Function for modified binary search
def binarySearch(n, C, arr):
      
    # Sort the indices in ascending order
    arr.sort(reverse = False)
  
    # Minimum possible distance
    lo = 0
  
    # Maximum possible distance
    hi = arr[n - 1]
    ans = 0
  
    # Run the loop until lo becomes
    # greater than hi
    while (lo <= hi):
        mid = int((lo + hi) / 2)
  
        # If not possibble, decrease value of hi
        if (isPossible(arr, n, C, mid) == False):
            hi = mid - 1
        else:
              
            # Update the answer
            ans = max(ans, mid)
            lo = mid + 1
  
    # Return maximum possible distance
    return ans
  
# Driver code
if __name__ == '__main__':
    C = 4
    arr = [1, 2, 5, 8, 10, 18]
    n = len(arr)
    print(binarySearch(n, C, arr))
  
# This code is contributed by
# Surendra_Gangwar


C#
// C# implementation of the approach
using System;
  
class GFG
{
// Function to check if it is possible
// to place C magnets assuming mid as
// maximum possible distance
static bool isPossible(int []arr, int n, 
                        int C, int mid)
{
    // Variable magnet will store count of magnets
    // that got placed and currPosition will store
    // the position of last placed magnet
    int magnet = 1, currPosition = arr[0];
  
    for (int i = 1; i < n; i++) 
    {
  
        // If difference between current index and
        // last placed index is greater than or equal to mid
        // it will allow placing magnet to this index
        if (arr[i] - currPosition >= mid)
        {
  
            magnet++;
  
            // Now this index will become
            // last placed index
            currPosition = arr[i];
  
            // If count of magnets placed becomes C
            if (magnet == C)
                return true;
        }
    }
  
    // If count of placed magnet is
    // less than C then return false
    return false;
}
  
// Function for modified binary search
static int binarySearch(int n, int C, int []arr)
{
    int lo, hi, mid, ans;
  
    // Sort the indices in ascending order
    Array.Sort(arr);
  
    // Minimum possible distance
    lo = 0;
  
    // Maximum possible distance
    hi = arr[n - 1];
  
    ans = 0;
  
    // Run the loop until lo becomes
    // greater than hi
    while (lo <= hi) 
    {
  
        mid = (lo + hi) / 2;
  
        // If not possibble, decrease value of hi
        if (!isPossible(arr, n, C, mid))
            hi = mid - 1;
        else 
        {
  
            // Update the answer
            ans = Math.Max(ans, mid);
            lo = mid + 1;
        }
    }
  
    // Return maximum possible distance
    return ans;
}
  
// Driver code
static void Main()
{
    int C = 4;
    int []arr = { 1, 2, 5, 8, 10, 18 };
    int n = arr.Length;
    Console.WriteLine(binarySearch(n, C, arr));
}
}
  
// This code is contributed by chandan_jnu


PHP
= $mid)
        {
            $magnet++;
  
            // Now this index will become
            // last placed index
            $currPosition = $arr[$i];
  
            // If count of magnets placed becomes C
            if ($magnet == $C)
                return true;
        }
    }
  
    // If count of placed magnet is
    // less than C then return false
    return false;
}
  
// Function for modified binary search
function binarySearch($n, $C, $arr)
{
  
    // Sort the indices in ascending order
    sort($arr, 0);
  
    // Minimum possible distance
    $lo = 0;
  
    // Maximum possible distance
    $hi = $arr[$n - 1];
  
    $ans = 0;
  
    // Run the loop until lo becomes
    // greater than hi
    while ($lo <= $hi) 
    {
        $mid = ($lo + $hi) / 2;
  
        // If not possibble, decrease value of hi
        if (!isPossible($arr, $n, $C, $mid))
            $hi = $mid - 1;
        else
        {
  
            // Update the answer
            $ans = max($ans, $mid);
            $lo = $mid + 1;
        }
    }
  
    // Return maximum possible distance
    return $ans;
}
  
// Driver code
$C = 4;
$arr = array(1, 2, 5, 8, 10, 18);
$n = sizeof($arr);
echo binarySearch($n, $C, $arr) . "\n";
  
// This code is contributed 
// by Akanksha Rai
?>


输出:
4

时间复杂度: O(n * log(n))