Given an array stations[] of integers representing the position of N points along a straight line and an integer k, the task is to find the minimum value of the maximum distance d between adjacent gas stations after adding K more gas stations anywhere in between, not necessarily on an integer position.
Note: Stations are in strictly increasing order
Examples:
Input: stations[] = {1, 2, 3, 4, 5}, K = 2
Output: 1.00
Explanation: Since all gaps are already equal (1 unit each), adding extra stations in between does not reduce the maximum distance.Input: stations[] = {
3, 6, 12, 19, 33}, K = 3
Output: 6.00
Explanation: The largest gap is 14 (between 19 and 33). Adding 2 stations there splits it into ≈4.67. The next largest gap is 7 (between 12 and 19). Adding 1 station splits it into 3.5. Now the maximum gap left is 6.
[Expected Approach] Binary Search - O(n*log m) Time and O(1) Space :
The given problem can be solved by using Binary Search. The idea is to perform a binary search on the value D in the range [0, 108] where D represents the value of the maximum distance between the adjacent points after adding K points.
Step By Step Implementation:
- Initialize variables, low = 1 and high = 108, where low represents the lower bound and high represents the upper bound of the binary search.
- Create a function isPossible(), which returns the boolean value of whether it is possible to add K points in the array such that the maximum distance between adjacent points is D. It is based on the observation that for two adjacent points (i, j), the number of points required to be placed in their middle such that the maximum distance between them is D = (j -i)/D.
- Therefore, traverse the range using the binary search algorithm discussed here, and if for the mid-value D in the range [X, Y], if isPossible(D) is false, then iterate in the upper half of the range i.e, [D, Y]. Otherwise, iterate on the lower half i.e, [X, D].
- Iterate a loop until (high - low) > 10-6.
- The value stored in low is the required answer.
Below is the implementation of the above approach:
// C++ program for the above approach
#include <iostream>
#include <algorithm>
#include <vector>
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, vector<int>& arr, int K) {
// Stores the count of point used
int used = 0;
// Iterate over all given points
for (int i = 0; i < (int)arr.size() - 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(vector<int>& stations, 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, 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()
{
vector<int>arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int K = 9;
cout << minMaxDist(arr, K);
return 0;
}
// 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 K) {
// Stores the count of point used
int used = 0;
// Iterate over all given points
for (int i = 0; i < arr.length - 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 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, K)) {
// Update the current range
// to lower half
high = mid;
}
// Update the current range
// to upper half
else {
low = mid;
}
}
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;
System.out.printf("%.1f", minMaxDist(arr, K));
}
}
# 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, K):
# Stores the count of point used
used = 0
# Iterate over all given points
for i in range(len(arr) - 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, K):
# Stores the lower bound and upper
# bound of the given range
low, high = 0, 1e8
# Perform binary search
while (high - low > 1e-6):
# Find the middle value
mid = (low + high) / 2.0
if isPossible(mid, stations, K):
# Update the current range
# to lower half
high = mid
else:
# Update the current range
# to upper half
low = mid
return round(low, 2)
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
K = 9
print(minMaxDist(arr, K))
# This code is contributed by AnkThon
// 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 Program to implement
// the above approach
// Function to check if it is possible
// to add K points such that the maximum
// distance between adjacent points is D
function isPossible(D, arr, K) {
// Stores the count of point used
let used = 0;
// Iterate over all given points
for (let i = 0; i < arr.length - 1; ++i) {
// Add number of points required
// to be placed between ith
// and (i+1)th point
used += Math.floor((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
function minMaxDist(stations, K) {
// Stores the lower bound and upper
// bound of the given range
let low = 0, high = 1e8;
// Perform binary search
while (high - low > 1e-6) {
// Find the middle value
let mid = (low + high) / 2.0;
if (isPossible(mid, stations, K)) {
// Update the current range
// to lower half
high = mid;
}
// Update the current range
// to upper half
else {
low = mid;
}
}
return low;
}
// Driver Code
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let K = 9;
console.log(minMaxDist(arr, K).toFixed(2));
// This code is contributed by Potta Lokesh
Output
0.5
Time Complexity: O(N*log M), where the value of M is 1014.
Auxiliary Space: O(1)