在相邻点之间的任意位置添加 K 个点后,最小化相邻点之间的最大距离
给定一个包含N个整数的数组arr[]表示N个点在一条直线上的位置和一个整数K ,任务是在中间任意位置添加K个点后,找到相邻点之间最大距离的最小值,不一定在一个整数位置。
例子:
Input: arr[] = {2, 4, 8, 10}, K = 1
Output: 2
Explanation: A point at position 6 can be added. So the new array of points become {2, 4, 6, 8, 10} and the maximum distance between two adjacent points is 2 which is minimum possible.
Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, K = 9
Output: 0.5
方法:给定的问题可以通过使用二分搜索来解决。其思想是对[0, 10 8 ]范围内的值D进行二分查找,其中D表示添加K个点后相邻点之间的最大距离值。请按照以下步骤解决给定的问题:
- 初始化变量, low = 1和high = 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)