Given a sorted array arr of size n, containing positive integer positions of n gas stations on the X-axis, and an integer k, place k new gas stations on the X-axis. The new gas stations can be placed anywhere on the non-negative side of the X-axis, including non-integer positions. Let dist be the maximum distance between adjacent gas stations after adding the k new gas stations. Find the minimum value of dist.
Input: n = 10, arr = [1, 2, 3, 4, 5, 6 ,7, 8, 9, 10], k = 10
Output: 0.50000
Explanation: One of the possible ways to place 10 gas stations is [1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10]. Thus the maximum difference between adjacent gas stations is 0.5. Hence, the value of dist is 0.5. It can be shown that there is no possible way to add 10 gas stations in such a way that the value of dist is lower than this.
Input : n = 10, arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 1
Output: 1.00000
Explanation: One of the possible ways to place 1 gas station is [1, 1.5, 2, 3, 4, 5, 6, 7, 8, 9, 10]. Thus the maximum difference between adjacent gas stations is still 1. Hence, the value of dist is 1. It can be shown that there is no possible way to add 1 gas station in such a way that the value of dist is lower than this.
Input: n = 10, arr= [3, 6, 12, 19, 33, 44, 67, 72, 89, 95], k = 2
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
/* Function to minimize the maximum
distance between gas stations */
double minimiseMaxDistance(vector<int>& arr, int k) {
int n = arr.size();
/* Array to store how many gas
stations are placed in each section*/
vector<int> howMany(n - 1, 0);
// Place k gas stations
for (int gasStations = 1; gasStations <= k; gasStations++) {
double maxSection = -1;
int maxInd = -1;
/* Find the maximum section
and insert the gas station*/
for (int i = 0; i < n - 1; i++) {
double diff = arr[i + 1] - arr[i];
double sectionLength = diff / (howMany[i] + 1);
/* Update the maximum section
length and its index */
if (sectionLength > maxSection) {
maxSection = sectionLength;
maxInd = i;
}
}
/* Insert the current gas
station into the section */
howMany[maxInd]++;
}
// Find the maximum distance (answer)
double maxAns = -1;
for (int i = 0; i < n - 1; i++) {
double diff = arr[i + 1] - arr[i];
double sectionLength = diff / (howMany[i] + 1);
maxAns = max(maxAns, sectionLength);
}
return maxAns;
}
};
int main() {
vector<int> arr = {1, 2, 3, 4, 5};
int k = 4;
// Create an instance of the Solution class
Solution sol;
// Call the minimiseMaxDistance method and print the result
long double ans = sol.minimiseMaxDistance(arr, k);
cout << "The answer is: " << ans << "\n";
return 0;
}
import java.util.*;
class Solution {
/* Function to minimize the maximum
distance between gas stations */
public static double minimiseMaxDistance(int[] arr, int k) {
int n = arr.length;
/* Array to store how many gas
stations are placed in each section*/
int[] howMany = new int[n - 1];
//Pick and place k gas stations
for (int gasStations = 1; gasStations <= k; gasStations++) {
double maxSection = -1;
int maxInd = -1;
/* Find the maximum section
and insert the gas station*/
for (int i = 0; i < n - 1; i++) {
double diff = arr[i + 1] - arr[i];
double sectionLength = diff / (double)(howMany[i] + 1);
/* Update the maximum section
length and its index */
if (sectionLength > maxSection) {
maxSection = sectionLength;
maxInd = i;
}
}
/* Insert the current gas
station into the section */
howMany[maxInd]++;
}
//Find the maximum distance i.e. the answer:
double maxAns = -1;
for (int i = 0; i < n - 1; i++) {
double diff = arr[i + 1] - arr[i];
double sectionLength =
diff / (double)(howMany[i] + 1);
maxAns = Math.max(maxAns, sectionLength);
}
return maxAns;
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
int k = 4;
// Create an instance of the Solution class
Solution sol = new Solution();
// Call the minimiseMaxDistance method and print the result
double ans = sol.minimiseMaxDistance(arr, k);
System.out.println("The answer is: " + ans);
}
}
class Solution:
""" Function to minimize the maximum
distance between gas stations """
def minimiseMaxDistance(self, arr, k):
n = len(arr)
howMany = [0] * (n - 1)
# Pick and place k gas stations
for gasStations in range(1, k + 1):
maxSection = -1
maxInd = -1
""" Find the maximum section
and insert the gas station"""
for i in range(n - 1):
diff = arr[i + 1] - arr[i]
sectionLength = diff / (howMany[i] + 1)
""" Update the maximum section
length and its index """
if sectionLength > maxSection:
maxSection = sectionLength
maxInd = i
""" Insert the current gas
station into the section"""
howMany[maxInd] += 1
# Find the maximum distance i.e. the answer
maxAns = -1
for i in range(n - 1):
diff = arr[i + 1] - arr[i]
sectionLength = diff / (howMany[i] + 1)
maxAns = max(maxAns, sectionLength)
return maxAns
if __name__ == "__main__":
arr = [1, 2, 3, 4, 5]
k = 4
# Create an instance of the Solution class
sol = Solution()
# Call the minimiseMaxDistance method and print the result
ans = sol.minimiseMaxDistance(arr, k)
print(f"The answer is: {ans:.6f}")
class Solution {
/* Function to minimize the maximum
distance between gas stations */
minimiseMaxDistance(arr, k) {
const n = arr.length;
/* Array to store how many gas
stations are placed in each section*/
const howMany = new Array(n - 1).fill(0);
//Pick and place k gas stations
for (let gasStations = 1; gasStations <= k; gasStations++) {
let maxSection = -1;
let maxInd = -1;
/* Find the maximum section
and insert the gas station*/
for (let i = 0; i < n - 1; i++) {
const diff = arr[i + 1] - arr[i];
/* Update the maximum section
length and its index */
const sectionLength = diff / (howMany[i] + 1);
if (sectionLength > maxSection) {
maxSection = sectionLength;
maxInd = i;
}
}
/* Insert the current gas
station into the section */
howMany[maxInd]++;
}
//Find the maximum distance i.e. the answer
let maxAns = -1;
for (let i = 0; i < n - 1; i++) {
const diff = arr[i + 1] - arr[i];
const sectionLength = diff / (howMany[i] + 1);
maxAns = Math.max(maxAns, sectionLength);
}
return maxAns;
}
}
const arr = [1, 2, 3, 4, 5];
const k = 4;
// Create an instance of the Solution class
const sol = new Solution();
// Call the minimiseMaxDistance method and print the result
const ans = sol.minimiseMaxDistance(arr, k);
console.log(`The answer is: ${ans}`);
howMany
of size n-1, to keep track of the number of placed gas stations and a priority queue that uses max heap, where n is the size of array provided in question.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
/* Function to minimize the maximum
distance between gas stations*/
long double minimiseMaxDistance(vector<int> &arr, int k) {
int n = arr.size();
/* Array to store how many gas
stations are placed in each section*/
vector<int> howMany(n - 1, 0);
/* Max heap to store sections by
their current maximum distance*/
priority_queue<pair<long double, int>> pq;
/* Insert first n-1 elements into priority
queue with respective distance values*/
for (int i = 0; i < n - 1; i++) {
pq.push({(long double)(arr[i + 1] - arr[i]), i});
}
for (int gasStations = 1; gasStations <= k; gasStations++) {
/* Find the maximum section
and insert the gas station*/
auto tp = pq.top();
pq.pop();
// Index of the section
int secInd = tp.second;
// Insert current gas station into section
howMany[secInd]++;
/* Calculate the initial difference
between adjacent gas stations*/
long double inidiff = (long double)(arr[secInd + 1] - arr[secInd]);
/* Calculate the new section length
after inserting another gas station*/
long double newSecLen = inidiff / (long double)(howMany[secInd] + 1);
/* Push the updated section
back into the priority queue*/
pq.push({newSecLen, secInd});
}
/* Return the maximum distance in
the top section of the heap*/
return pq.top().first;
}
};
int main() {
vector<int> arr = {1, 2, 3, 4, 5};
int k = 4;
// Create an instance of the Solution class
Solution sol;
// Call the minimiseMaxDistance method and print the result
long double ans = sol.minimiseMaxDistance(arr, k);
cout << "The answer is: " << ans << "\n";
return 0;
}
import java.util.PriorityQueue;
class Solution {
/* Function to minimize the maximum
distance between gas stations */
public double minimiseMaxDistance(int[] arr, int k) {
int n = arr.length; // Size of array
/* Array to store how many gas
stations are placed in each section */
int[] howMany = new int[n - 1];
/* Max heap to store sections by
their current maximum distance */
PriorityQueue pq = new PriorityQueue<>((Pair a, Pair b) -> Double.compare(b.first, a.first));
/* Insert first n-1 elements into priority
queue with respective distance values */
for (int i = 0; i < n - 1; i++) {
pq.add(new Pair(arr[i + 1] - arr[i], i));
}
for (int gasStations = 1; gasStations <= k; gasStations++) {
/* Find the maximum section
and insert the gas station */
Pair tp = pq.poll();
// Index of the section
int secInd = tp.second;
// Insert current gas station into section
howMany[secInd]++;
/* Calculate the initial difference
between adjacent gas stations */
double inidiff = arr[secInd + 1] - arr[secInd];
/* Calculate the new section length
after inserting another gas station */
double newSecLen = inidiff / (double) (howMany[secInd] + 1);
/* Push the updated section
back into the priority queue */
pq.add(new Pair(newSecLen, secInd));
}
/* Return the maximum distance in
the top section of the heap */
return pq.peek().first;
}
/* Nested Pair class */
private static class Pair {
double first;
int second;
Pair(double first, int second) {
this.first = first;
this.second = second;
}
}
/* Main method for testing */
public static void main(String[] args) {
Solution solution = new Solution();
int[] arr = {1, 2, 8, 10};
int k = 3;
double result = solution.minimiseMaxDistance(arr, k);
System.out.println("Minimum Maximum Distance: " + result);
}
}
import heapq
class Solution:
""" Function to minimize the maximum
distance between gas stations """
def minimiseMaxDistance(self, arr, k):
n = len(arr)
""" Array to store how many gas
stations are placed in each section """
howMany = [0] * (n - 1)
""" Min heap to store sections by
their current maximum distance """
pq = []
""" Insert first n-1 elements into priority
queue with respective distance values """
for i in range(n - 1):
heapq.heappush(pq, (-float(arr[i + 1] - arr[i]), i))
for gasStations in range(1, k + 1):
""" Find the maximum section
and insert the gas station """
neg_dist, secInd = heapq.heappop(pq)
# Get the section with maximum distance
max_dist = -neg_dist
# Insert current gas station into section
howMany[secInd] += 1
""" Calculate the initial difference
between adjacent gas stations """
inidiff = float(arr[secInd + 1] - arr[secInd])
""" Calculate the new section length
after inserting another gas station """
newSecLen = inidiff / (howMany[secInd] + 1)
""" Push the updated section
back into the priority queue """
heapq.heappush(pq, (-newSecLen, secInd))
""" Return the maximum distance in
the top section of the heap"""
return -pq[0][0]
if __name__ == "__main__":
arr = [1, 2, 3, 4, 5]
k = 4
# Create an instance of the Solution class
sol = Solution()
# Call the minimiseMaxDistance method and print the result
ans = sol.minimiseMaxDistance(arr, k)
print(f"The answer is: {ans}")
class Solution {
/* Function to minimize the maximum
distance between gas stations */
minimiseMaxDistance(arr, k) {
const n = arr.length; // Size of array
/* Array to store how many gas
stations are placed in each section */
const howMany = new Array(n - 1).fill(0);
/* Min heap to store sections by
their current maximum distance */
const pq = [];
/* Insert first n-1 elements into priority
queue with respective distance values */
for (let i = 0; i < n - 1; i++) {
pq.push([- (arr[i + 1] - arr[i]), i]);
}
for (let gasStations = 1; gasStations <= k; gasStations++) {
/* Find the maximum section
and insert the gas station */
pq.sort((a, b) => b[0] - a[0]);
// Get the section with maximum distance
const [negDist, secInd] = pq.pop();
// Insert current gas station into section
howMany[secInd]++;
/* Calculate the initial difference
between adjacent gas stations */
const inidiff = arr[secInd + 1] - arr[secInd];
/* Calculate the new section length
after inserting another gas station */
const newSecLen = inidiff / (howMany[secInd] + 1);
/* Push the updated section
back into the priority queue */
pq.push([-newSecLen, secInd]);
}
/* Return the maximum distance in
the top section of the heap*/
return -pq[0][0];
}
}
const arr = [1, 2, 3, 4, 5];
const k = 4;
// Create an instance of the Solution class
const sol = new Solution();
// Call the minimiseMaxDistance method and print the result
const ans = sol.minimiseMaxDistance(arr, k);
console.log(`The answer is: ${ans}`);
The idea here is to use the Binary Search algorithm to optimize the approach. The primary objective of the Binary Search algorithm is to efficiently determine the appropriate half to eliminate, thereby reducing the search space by half. It does this by determining a specific condition that ensures that the target is not present in that half.
Observation:Binary search is being applied on the answer, specifically on the possible values of distances. Therefore, a method needs to be devised to determine the number of gas stations that can be placed for a particular value of distance.
Working of minimiseMaxDistance(arr, k):Please refer to the video for complete dry run.
#include <bits/stdc++.h>
using namespace std;
class Solution {
private:
/* Function to calculate the number of gas
stations required for given distance*/
int numberOfGasStationsRequired(long double dist, vector<int> &arr) {
// Size of the array
int n = arr.size();
int cnt = 0;
for (int i = 1; i < n; i++) {
/* Calculate number of gas stations
needed between two points*/
int numberInBetween = ((arr[i] - arr[i - 1]) / dist);
// Adjust if exact distance fits perfectly
if ((arr[i] - arr[i - 1]) == (dist * numberInBetween)) {
numberInBetween--;
}
cnt += numberInBetween;
}
return cnt;
}
public:
/* Function to minimize the maximum
distance between gas stations*/
long double minimiseMaxDistance(vector<int> &arr, int k) {
int n = arr.size();
long double low = 0;
long double high = 0;
/* Find the maximum distance between
consecutive gas stations*/
for (int i = 0; i < n - 1; i++) {
high = max(high, (long double)(arr[i + 1] - arr[i]));
}
/* Apply Binary search to find the
minimum possible maximum distance*/
long double diff = 1e-6;
while (high - low > diff) {
long double mid = (low + high) / 2.0;
int cnt = numberOfGasStationsRequired(mid, arr);
/* Adjust the search range based on
the number of gas stations required*/
if (cnt > k) {
low = mid;
} else {
high = mid;
}
}
// Return the smallest maximum distance found
return high;
}
};
int main() {
vector<int> arr = {1, 2, 3, 4, 5};
int k = 4;
// Create an instance of the Solution class
Solution sol;
// Call the minimiseMaxDistance method and print the result
long double ans = sol.minimiseMaxDistance(arr, k);
cout << "The answer is: " << ans << "\n";
return 0;
}
import java.util.*;
class Solution {
/* Function to calculate the number of gas
stations required for given distance*/
private int numberOfGasStationsRequired(double dist, int[] arr) {
// Size of the array
int n = arr.length;
int cnt = 0;
for (int i = 1; i < n; i++) {
/* Calculate number of gas stations
needed between two points*/
int numberInBetween = (int) ((arr[i] - arr[i - 1]) / dist);
// Adjust if exact distance fits perfectly
if ((arr[i] - arr[i - 1]) == (dist * numberInBetween)) {
numberInBetween--;
}
cnt += numberInBetween;
}
return cnt;
}
/* Function to minimize the maximum
distance between gas stations*/
public double minimiseMaxDistance(int[] arr, int k) {
int n = arr.length;
double low = 0;
double high = 0;
/* Find the maximum distance between
consecutive gas stations*/
for (int i = 0; i < n - 1; i++) {
high = Math.max(high, arr[i + 1] - arr[i]);
}
/* Apply Binary search to find the
minimum possible maximum distance*/
double diff = 1e-6;
while (high - low > diff) {
double mid = (low + high) / 2.0;
int cnt = numberOfGasStationsRequired(mid, arr);
/* Adjust the search range based on
the number of gas stations required*/
if (cnt > k) {
low = mid;
} else {
high = mid;
}
}
// Return smallest maximum distance found
return high;
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
int k = 4;
// Create an instance of the Solution class
Solution sol = new Solution();
// Call the minimiseMaxDistance method and print the result
double ans = sol.minimiseMaxDistance(arr, k);
System.out.println("The answer is: " + ans);
}
}
import math
class Solution:
# Function to calculate the number of gas
# stations required for given distance
def numberOfGasStationsRequired(self, dist, arr):
n = len(arr)
cnt = 0
for i in range(1, n):
# Calculate number of gas stations
# needed between two points
numberInBetween = (arr[i] - arr[i - 1]) / dist
# Adjust if exact distance fits perfectly
if (arr[i] - arr[i - 1]) == (dist * int(numberInBetween)):
numberInBetween -= 1
cnt += int(numberInBetween)
return cnt
# Function to minimize the maximum
# distance between gas stations
def minimiseMaxDistance(self, arr, k):
n = len(arr)
low = 0
high = 0
# Find the maximum distance between
# consecutive gas stations
for i in range(n - 1):
high = max(high, arr[i + 1] - arr[i])
# Apply Binary search to find the
# minimum possible maximum distance
diff = 1e-6
while high - low > diff:
mid = (low + high) / 2.0
cnt = self.numberOfGasStationsRequired(mid, arr)
# Adjust the search range based on the
# number of gas stations required
if cnt > k:
low = mid
else:
high = mid
# Return the smallest maximum distance found
return high
if __name__ == "__main__":
arr = [1, 2, 3, 4, 5]
k = 4
# Create an instance of the Solution class
sol = Solution()
# Call the minimiseMaxDistance method and print the result
ans = sol.minimiseMaxDistance(arr, k)
print(f"The answer is: {ans}")
class Solution {
/* Function to calculate the number of
gas stations required for given distance*/
numberOfGasStationsRequired(dist, arr) {
// Size of the array
const n = arr.length;
let cnt = 0;
for (let i = 1; i < n; i++) {
/* Calculate number of gas stations
needed between two points*/
const numberInBetween = Math.floor((arr[i] - arr[i - 1]) / dist);
// Adjust if exact distance fits perfectly
if ((arr[i] - arr[i - 1]) === dist * numberInBetween) {
cnt += numberInBetween - 1;
} else
cnt += numberInBetween;
}
return cnt;
}
/* Function to minimize the maximum
distance between gas stations*/
minimiseMaxDistance(arr, k) {
const n = arr.length;
let low = 0;
let high = 0;
/* Find the maximum distance between
consecutive gas stations*/
for (let i = 0; i < n - 1; i++) {
high = Math.max(high, arr[i + 1] - arr[i]);
}
const diff = 1e-6;
/* Apply Binary search to find the
minimum possible maximum distance*/
while (high - low > diff) {
const mid = (low + high) / 2.0;
const cnt = this.numberOfGasStationsRequired(mid, arr);
/* Adjust the search range based on
the number of gas stations required*/
if (cnt > k) {
low = mid;
} else {
high = mid;
}
}
// Return smallest maximum distance found
return high;
}
}
const arr = [1, 2, 3, 4, 5];
const k = 4;
// Create an instance of the Solution class
const sol = new Solution();
// Call the minimiseMaxDistance method and print the result
const ans = sol.minimiseMaxDistance(arr, k);
console.log(`The answer is: ${ans}`);
Q: How does floating-point precision affect the solution?
A: Since gas stations can be placed at non-integer positions, floating-point arithmetic is used. The binary search stops when the range of possible dist values is smaller than a specified precision (ϵ).
Q: What if the array has fewer than two gas stations?
A: If there is only one gas station (n=1), the gap is undefined. Any additional gas stations can be placed arbitrarily, making dist depend only on their positions.
Q: What if gas stations cannot be placed at arbitrary positions?
A: If new stations must be placed at predefined positions (e.g., integer locations), modify the feasibility check to only consider those positions and adjust the binary search accordingly.
Q: How would you handle dynamic updates (e.g., removing stations)?
A: For dynamic updates, maintain a sorted list of gas station positions. Use efficient data structures like balanced binary search trees to dynamically insert or remove stations and recompute dist.