Minimize Max Distance to Gas Station
Add k gas stations on a number line to minimize the maximum gap — binary search on the answer with a greedy feasibility check.
4 min read
binary-search
Problem#
Existing gas stations are on a number line. Add k more. Minimize the maximum gap between adjacent stations. Return that minimum gap (real-valued).
Examples#
stations = [1,2,3,4,5,6,7,8,9,10], k = 9→0.5
Constraints#
1 <= stations.length, k <= 10^4. Real-valued answer.
Approach#
Binary search on the answer d (in [0, maxGap]). For each gap g, we need floor(g / d) extra stations to split it into intervals ≤ d. Feasible iff total extra ≤ k. Use real-valued search until hi - lo < 1e-6.
Solution#
class Solution {public: double minmaxGasDist(vector<int>& stations, int k) { double lo = 0, hi = 1e8; auto need = [&](double d) { long long total = 0; for (int i = 1; i < (int)stations.size(); ++i) { total += (long long)((stations[i] - stations[i - 1]) / d); } return total; }; for (int iter = 0; iter < 100 && hi - lo > 1e-6; ++iter) { double mid = (lo + hi) / 2; if (need(mid) > k) lo = mid; else hi = mid; } return lo; }};func minmaxGasDist(stations []int, k int) float64 { lo, hi := 0.0, 1e8 need := func(d float64) int64 { var total int64 for i := 1; i < len(stations); i++ { total += int64(float64(stations[i]-stations[i-1]) / d) } return total } for iter := 0; iter < 100 && hi-lo > 1e-6; iter++ { mid := (lo + hi) / 2 if need(mid) > int64(k) { lo = mid } else { hi = mid } } return lo}from typing import List
class Solution: def minmaxGasDist(self, stations: List[int], k: int) -> float: lo, hi = 0.0, 1e8
def need(d: float) -> int: total = 0 for i in range(1, len(stations)): total += int((stations[i] - stations[i - 1]) / d) return total
for _ in range(100): if hi - lo <= 1e-6: break mid = (lo + hi) / 2 if need(mid) > k: lo = mid else: hi = mid return lofunction minmaxGasDist(stations, k) { let lo = 0.0, hi = 1e8; const need = (d) => { let total = 0; for (let i = 1; i < stations.length; i++) { total += Math.floor((stations[i] - stations[i - 1]) / d); } return total; }; for (let iter = 0; iter < 100 && hi - lo > 1e-6; iter++) { const mid = (lo + hi) / 2; if (need(mid) > k) lo = mid; else hi = mid; } return lo;}class Solution { public double minmaxGasDist(int[] stations, int k) { double lo = 0, hi = 1e8; for (int iter = 0; iter < 100 && hi - lo > 1e-6; iter++) { double mid = (lo + hi) / 2; if (need(stations, mid) > k) lo = mid; else hi = mid; } return lo; }
private long need(int[] stations, double d) { long total = 0; for (int i = 1; i < stations.length; i++) { total += (long) ((stations[i] - stations[i - 1]) / d); } return total; }}function minmaxGasDist(stations: number[], k: number): number { let lo = 0.0, hi = 1e8; const need = (d: number): number => { let total = 0; for (let i = 1; i < stations.length; i++) { total += Math.floor((stations[i] - stations[i - 1]) / d); } return total; }; for (let iter = 0; iter < 100 && hi - lo > 1e-6; iter++) { const mid = (lo + hi) / 2; if (need(mid) > k) lo = mid; else hi = mid; } return lo;}Editorial#
Continuous-domain binary search: instead of lo < hi, run a fixed number of iterations or until the precision threshold. Each iteration halves the range, so 50–100 iterations give ample precision.
Complexity#
- Time: O(n × iterations).
- Space: O(1).
Concept revision#
Related#