📌  相关文章
📜  在相邻点之间的任意位置添加 K 个点后,最小化相邻点之间的最大距离

📅  最后修改于: 2022-05-13 01:56:09.619000             🧑  作者: Mango

在相邻点之间的任意位置添加 K 个点后,最小化相邻点之间的最大距离

给定一个包含N个整数的数组arr[]表示N个点在一条直线上的位置和一个整数K ,任务是在中间任意位置添加K个点后,找到相邻点之间最大距离的最小值,不一定在一个整数位置。

例子:

方法:给定的问题可以通过使用二分搜索来解决。其思想是对[0, 10 8 ]范围内的值D进行二分查找,其中D表示添加K个点后相邻点之间的最大距离值。请按照以下步骤解决给定的问题:

  • 初始化变量, low = 1high = 10 8 ,其中low表示下限, high表示二分查找的上限。
  • 创建一个函数isPossible() ,它返回布尔值是否可以在数组中添加K个点,使得相邻点之间的最大距离为D 。它基于以下观察:对于两个相邻点(i, j) ,需要放置在它们中间的点数使得它们之间的最大距离为D = (j -i)/D
  • 因此,使用这里讨论的二进制搜索算法遍历范围,如果对于范围[X, Y]中的中间值D ,如果isPossible(D)为 false,则在范围的上半部分进行迭代,即[ D,Y] 。否则,迭代下半部分,即[X, D]
  • 迭代一个循环,直到(high – low) > 10 -6
  • 存储在中的值是所需的答案。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to check if it is possible
// to add K points such that the maximum
// distance between adjacent points is D
bool isPossible(double D, int arr[],
                int N, int K)
{
    // Stores the count of point used
    int used = 0;
 
    // Iterate over all given points
    for (int i = 0; i < N - 1; ++i) {
 
        // Add number of points required
        // to be placed between ith
        // and (i+1)th point
        used += (int)((arr[i + 1]
                       - arr[i])
                      / D);
    }
 
    // Return answer
    return used <= K;
}
 
// Function to find the minimum value of
// maximum distance between adjacent points
// after adding K points any where between
double minMaxDist(int stations[], int N, int K)
{
    // Stores the lower bound and upper
    // bound of the given range
    double low = 0, high = 1e8;
 
    // Perform binary search
    while (high - low > 1e-6) {
 
        // Find the middle value
        double mid = (low + high) / 2.0;
 
        if (isPossible(mid, stations, N, K)) {
 
            // Update the current range
            // to lower half
            high = mid;
        }
 
        // Update the current range
        // to upper half
        else {
            low = mid;
        }
    }
 
    return low;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int K = 9;
    int N = sizeof(arr) / sizeof(arr[0]);
 
    cout << minMaxDist(arr, N, K);
 
    return 0;
}


Java
// Java program for the above approach
import java.math.BigDecimal;
 
class GFG {
 
    // Function to check if it is possible
    // to add K points such that the maximum
    // distance between adjacent points is D
    public static boolean isPossible(double D, int arr[],
                                     int N, int K)
    {
        // Stores the count of point used
        int used = 0;
 
        // Iterate over all given points
        for (int i = 0; i < N - 1; ++i) {
 
            // Add number of points required
            // to be placed between ith
            // and (i+1)th point
            used += (int) ((arr[i + 1] - arr[i]) / D);
        }
 
        // Return answer
        return used <= K;
    }
 
    // Function to find the minimum value of
    // maximum distance between adjacent points
    // after adding K points any where between
    public static double minMaxDist(int stations[], int N, int K)
    {
       
        // Stores the lower bound and upper
        // bound of the given range
        double low = 0, high = 1e8;
 
        // Perform binary search
        while (high - low > 1e-6) {
 
            // Find the middle value
            double mid = (low + high) / 2.0;
 
            if (isPossible(mid, stations, N, K)) {
 
                // Update the current range
                // to lower half
                high = mid;
            }
 
            // Update the current range
            // to upper half
            else {
                low = mid;
            }
        }
       
        // System.out.printf("Value: %.2f", low);
        return low;
    }
 
    // Driver Code
    public static void main(String args[])
    {
        int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        int K = 9;
        int N = arr.length;
 
        System.out.printf("%.1f", minMaxDist(arr, N, K));
    }
}
 
// This code is contributed by _saurabh_jaiswal.


Python3
# Python3 program for the above approach
 
# Function to check if it is possible
# to add K points such that the maximum
# distance between adjacent points is D
def isPossible(D, arr, N, K) :
 
    # Stores the count of point used
    used = 0;
 
    # Iterate over all given points
    for i in range(N - 1) :
 
        # Add number of points required
        # to be placed between ith
        # and (i+1)th point
        used += int((arr[i + 1] - arr[i]) / D);
 
    # Return answer
    return used <= K;
 
# Function to find the minimum value of
# maximum distance between adjacent points
# after adding K points any where between
def minMaxDist(stations, N, K) :
     
    # Stores the lower bound and upper
    # bound of the given range
    low = 0; high = 1e8;
 
    # Perform binary search
    while (high - low > 1e-6) :
 
        # Find the middle value
        mid = (low + high) / 2.0;
 
        if (isPossible(mid, stations, N, K)) :
 
            # Update the current range
            # to lower half
            high = mid;
 
        # Update the current range
        # to upper half
        else :
             
            low = mid;
 
    return round(low, 2);
 
# Driver Code
if __name__ == "__main__" :
 
    arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
    K = 9;
    N = len(arr);
 
    print(minMaxDist(arr, N, K));
     
    # This code is contributed by AnkThon


C#
// C# program for the above approach
using System;
 
public class GFG {
 
    // Function to check if it is possible
    // to add K points such that the maximum
    // distance between adjacent points is D
    public static bool isPossible(double D, int []arr,
                                     int N, int K)
    {
       
        // Stores the count of point used
        int used = 0;
 
        // Iterate over all given points
        for (int i = 0; i < N - 1; ++i) {
 
            // Add number of points required
            // to be placed between ith
            // and (i+1)th point
            used += (int) ((arr[i + 1] - arr[i]) / D);
        }
 
        // Return answer
        return used <= K;
    }
 
    // Function to find the minimum value of
    // maximum distance between adjacent points
    // after adding K points any where between
    public static double minMaxDist(int []stations, int N, int K)
    {
       
        // Stores the lower bound and upper
        // bound of the given range
        double low = 0, high = 1e8;
 
        // Perform binary search
        while (high - low > 1e-6) {
 
            // Find the middle value
            double mid = (low + high) / 2.0;
 
            if (isPossible(mid, stations, N, K)) {
 
                // Update the current range
                // to lower half
                high = mid;
            }
 
            // Update the current range
            // to upper half
            else {
                low = mid;
            }
        }
       
        // Console.Write("Value: %.2f", low);
        return low;
    }
 
    // Driver Code
    public static void Main(String []args)
    {
        int []arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        int K = 9;
        int N = arr.Length;
 
        Console.Write("{0:F1}", minMaxDist(arr, N, K));
    }
}
 
 
 
// This code is contributed by 29AjayKumar


Javascript


Java
import java.util.Collections;
import java.util.PriorityQueue;
 
class GFG {
    public static void main(String[] args)
    {
        int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        int K = 9;
        int N = arr.length;
 
        // Max heap initialisation
        PriorityQueue pq = new PriorityQueue<>(
            N + K, Collections.reverseOrder());
 
        // Add adjacent distances to max heap
        for (int i = 1; i < N; i++) {
            pq.add((float)arr[i] - (float)arr[i - 1]);
        }
 
        // For K times, half the maximum distance
        for (int i = 0; i < K; i++) {
            float temp = pq.poll();
            pq.add(temp / 2);
            pq.add(temp / 2);
        }
        System.out.println(pq.peek());
    }
}
// This code is contributed by _govardhani


输出:
0.5

时间复杂度: O(N*log M),其中 M 的值为 10 14
辅助空间: O(1)

替代方法:问题归结为将最大距离最小化 K 倍。每次,为了获得最大距离,我们可以使用最大堆。

步骤-1:遍历数组元素并将相邻数组元素的距离存储在最大堆中。

Step-2 : 对于 K 次,从堆中轮询最大元素并添加到堆中 max/2, max/2 即,我们每次都将最大距离减少到两个相等的一半。

Step-3:迭代K次后返回最大元素。

下面是上述方法的实现:

Java

import java.util.Collections;
import java.util.PriorityQueue;
 
class GFG {
    public static void main(String[] args)
    {
        int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        int K = 9;
        int N = arr.length;
 
        // Max heap initialisation
        PriorityQueue pq = new PriorityQueue<>(
            N + K, Collections.reverseOrder());
 
        // Add adjacent distances to max heap
        for (int i = 1; i < N; i++) {
            pq.add((float)arr[i] - (float)arr[i - 1]);
        }
 
        // For K times, half the maximum distance
        for (int i = 0; i < K; i++) {
            float temp = pq.poll();
            pq.add(temp / 2);
            pq.add(temp / 2);
        }
        System.out.println(pq.peek());
    }
}
// This code is contributed by _govardhani

时间复杂度: O(NlogN)
辅助空间: O(N+K)