Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

774. Minimize Max Distance to Gas Station - Leetcode Solution

Code Implementation

import heapq

class Solution:
    def minmaxGasDist(self, stations, K):
        # Calculate all gaps between stations
        gaps = []
        for i in range(1, len(stations)):
            gaps.append(stations[i] - stations[i-1])
        
        # Binary search for the answer
        left, right = 0, max(gaps)
        eps = 1e-6

        def possible(D):
            # For each gap, compute how many extra stations are needed
            count = 0
            for gap in gaps:
                # Number of stations needed in this gap
                count += int(gap / D)
            return count <= K

        while right - left > eps:
            mid = (left + right) / 2
            if possible(mid):
                right = mid
            else:
                left = mid
        return left
      
class Solution {
public:
    double minmaxGasDist(vector<int>& stations, int K) {
        vector<double> gaps;
        for (int i = 1; i < stations.size(); ++i) {
            gaps.push_back(stations[i] - stations[i-1]);
        }
        double left = 0, right = *max_element(gaps.begin(), gaps.end());
        double eps = 1e-6;

        auto possible = [&](double D) {
            int count = 0;
            for (double gap : gaps) {
                count += int(gap / D);
            }
            return count <= K;
        };

        while (right - left > eps) {
            double mid = (left + right) / 2;
            if (possible(mid))
                right = mid;
            else
                left = mid;
        }
        return left;
    }
};
      
class Solution {
    public double minmaxGasDist(int[] stations, int K) {
        int n = stations.length;
        double[] gaps = new double[n-1];
        for (int i = 1; i < n; ++i) {
            gaps[i-1] = stations[i] - stations[i-1];
        }
        double left = 0, right = 0;
        for (double gap : gaps) right = Math.max(right, gap);
        double eps = 1e-6;

        while (right - left > eps) {
            double mid = (left + right) / 2;
            int count = 0;
            for (double gap : gaps) {
                count += (int)(gap / mid);
            }
            if (count <= K)
                right = mid;
            else
                left = mid;
        }
        return left;
    }
}
      
var minmaxGasDist = function(stations, K) {
    let gaps = [];
    for (let i = 1; i < stations.length; ++i) {
        gaps.push(stations[i] - stations[i-1]);
    }
    let left = 0, right = Math.max(...gaps);
    let eps = 1e-6;
    
    function possible(D) {
        let count = 0;
        for (let gap of gaps) {
            count += Math.floor(gap / D);
        }
        return count <= K;
    }
    
    while (right - left > eps) {
        let mid = (left + right) / 2;
        if (possible(mid))
            right = mid;
        else
            left = mid;
    }
    return left;
};
      

Problem Description

You are given an array stations representing the positions of gas stations along a straight road, sorted in increasing order. You are also given an integer K, which is the maximum number of additional gas stations you can add anywhere along the road (not necessarily at integer positions).

Your goal is to minimize the maximum distance between any two adjacent gas stations after adding up to K new stations. Return the minimized maximum distance as a floating point number.

  • There is always exactly one valid answer.
  • You cannot reuse or move existing stations.
  • All positions are real numbers, and you can add new stations at any real position between existing stations.

For example, if stations = [1, 4, 10] and K = 2, you can add stations to minimize the largest gap between any two consecutive stations.

Thought Process

The problem asks us to minimize the largest distance between any two consecutive gas stations by adding up to K new stations. The naive approach would be to try all possible placements of the new stations, but this quickly becomes infeasible as the number of possibilities grows exponentially.

Instead, we can reframe the problem: for a given candidate value D (maximum allowed distance), can we place the K stations such that all gaps are at most D? If we can, maybe we can do even better. If not, we need to allow a larger D.

This leads us to an optimization mindset: use binary search on D, the maximum allowed distance, and at each step check if the current D is feasible.

Solution Approach

  • Step 1: Calculate Gaps
    First, compute the distances between each pair of existing consecutive stations. These are the "gaps" we want to minimize.
  • Step 2: Binary Search on the Answer
    The answer (the minimized maximum distance) must be between 0 and the largest initial gap. We use binary search to find the smallest value D such that it's possible to insert at most K stations so that no gap exceeds D.
  • Step 3: Feasibility Check
    For each candidate D, iterate over the gaps. For a gap of length g, you need at least floor(g / D) stations to ensure no segment is longer than D. Sum these up for all gaps. If the total is less than or equal to K, D is feasible.
  • Step 4: Binary Search Loop
    Repeat the binary search until the difference between left and right is less than a tiny epsilon (e.g., 1e-6) to achieve the required precision.
  • Step 5: Return the Result
    The final value of left (or right) is the minimal possible maximum distance.

This approach is efficient because at each step, instead of exploring every placement, we only check if a given maximum gap is achievable, which is fast to compute.

Example Walkthrough

Let's walk through the example where stations = [1, 4, 10] and K = 2:

  1. The initial gaps are 3 (from 1 to 4) and 6 (from 4 to 10).
  2. We binary search for the minimal D. Let's try D = 3:
    • Gap 3: needs floor(3/3) = 1 new station
    • Gap 6: needs floor(6/3) = 2 new stations
    • Total needed: 1 + 2 = 3 (too many, since K=2)
  3. Increase D. Try D = 4:
    • Gap 3: needs floor(3/4) = 0 new stations
    • Gap 6: needs floor(6/4) = 1 new station
    • Total needed: 0 + 1 = 1 (can do with 2 stations, so try smaller D)
  4. Now try D = 3.5:
    • Gap 3: needs 0
    • Gap 6: needs floor(6/3.5) = 1
    • Total needed: 1 (still okay)
  5. Continue binary search between 3 and 3.5, narrowing down until the smallest feasible D is found.

The process continues until the answer converges to the minimal maximum distance possible, given the allowed number of new stations.

Time and Space Complexity

  • Brute-force Approach: Trying all possible placements of K stations has exponential time complexity, which is infeasible for large inputs.
  • Optimized (Binary Search) Approach:
    • Each binary search iteration takes O(N), where N is the number of gaps (stations.length - 1), since we check each gap.
    • The number of binary search iterations depends on the required precision (let's say P). Usually, it's about log2(range/precision).
    • Total time complexity: O(N * log(R/ε)), where R is the range of possible distances and ε is the precision.
    • Space complexity: O(N) for storing the gaps.

Summary

This problem is a classic example of using binary search on the answer to efficiently optimize a value under constraints. By reframing the task as a feasibility check for a given maximum gap, we avoid brute-force placement of stations and instead iteratively hone in on the minimal possible value. The approach is both elegant and efficient, leveraging the properties of monotonicity and the power of binary search.