# [774. 最小化去加油站的最大距离](https://leetcode.cn/problems/minimize-max-distance-to-gas-station)

[English Version](/solution/0700-0799/0774.Minimize%20Max%20Distance%20to%20Gas%20Station/README_EN.md)

## 题目描述

<!-- 这里写题目描述 -->

<p>整数数组 <code>stations</code> 表示 <strong>水平数轴</strong> 上各个加油站的位置。给你一个整数 <code>k</code> 。</p>

<p>请你在数轴上增设 <code>k</code> 个加油站,新增加油站可以位于 <strong>水平数轴</strong> 上的任意位置,而不必放在整数位置上。</p>

<p>设 <code>penalty()</code> 是:增设 <code>k</code> 个新加油站后,<strong>相邻</strong> 两个加油站间的最大距离。</p>
请你返回 <code>penalty()</code><strong> </strong>可能的最小值。与实际答案误差在 <code>10<sup>-6</sup></code> 范围内的答案将被视作正确答案。

<p> </p>

<p><strong>示例 1:</strong></p>

<pre>
<strong>输入:</strong>stations = [1,2,3,4,5,6,7,8,9,10], k = 9
<strong>输出:</strong>0.50000
</pre>

<p><strong>示例 2:</strong></p>

<pre>
<strong>输入:</strong>stations = [23,24,36,39,46,56,57,65,84,98], k = 1
<strong>输出:</strong>14.00000
</pre>

<p> </p>

<p><strong>提示:</strong></p>

<ul>
	<li><code>10 <= stations.length <= 2000</code></li>
	<li><code>0 <= stations[i] <= 10<sup>8</sup></code></li>
	<li><code>stations</code> 按 <strong>严格递增</strong> 顺序排列</li>
	<li><code>1 <= k <= 10<sup>6</sup></code></li>
</ul>

## 解法

<!-- 这里可写通用的实现逻辑 -->

**方法一:二分查找(浮点数二分)**

我们二分枚举相邻两个加油站间的距离,找到最小的距离,使得加油站的数量不超过 $k$。

时间复杂度 $O(n\log M)$。其中 $n$ 为加油站的数量;而 $M$ 为答案的范围,即 $10^8$ 除以答案的精度 $10^{-6}$。

<!-- tabs:start -->

### **Python3**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```python
class Solution:
    def minmaxGasDist(self, stations: List[int], k: int) -> float:
        def check(x):
            return sum(int((b - a) / x) for a, b in pairwise(stations)) <= k

        left, right = 0, 1e8
        while right - left > 1e-6:
            mid = (left + right) / 2
            if check(mid):
                right = mid
            else:
                left = mid
        return left
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java
class Solution {
    public double minmaxGasDist(int[] stations, int k) {
        double left = 0, right = 1e8;
        while (right - left > 1e-6) {
            double mid = (left + right) / 2.0;
            if (check(mid, stations, k)) {
                right = mid;
            } else {
                left = mid;
            }
        }
        return left;
    }

    private boolean check(double x, int[] stations, int k) {
        int s = 0;
        for (int i = 0; i < stations.length - 1; ++i) {
            s += (int) ((stations[i + 1] - stations[i]) / x);
        }
        return s <= k;
    }
}
```

### **C++**

```cpp
class Solution {
public:
    double minmaxGasDist(vector<int>& stations, int k) {
        double left = 0, right = 1e8;
        auto check = [&](double x) {
            int s = 0;
            for (int i = 0; i < stations.size() - 1; ++i) {
                s += (int) ((stations[i + 1] - stations[i]) / x);
            }
            return s <= k;
        };
        while (right - left > 1e-6) {
            double mid = (left + right) / 2.0;
            if (check(mid)) {
                right = mid;
            } else {
                left = mid;
            }
        }
        return left;
    }
};
```

### **Go**

```go
func minmaxGasDist(stations []int, k int) float64 {
	check := func(x float64) bool {
		s := 0
		for i, v := range stations[:len(stations)-1] {
			s += int(float64(stations[i+1]-v) / x)
		}
		return s <= k
	}
	var left, right float64 = 0, 1e8
	for right-left > 1e-6 {
		mid := (left + right) / 2.0
		if check(mid) {
			right = mid
		} else {
			left = mid
		}
	}
	return left
}
```

### **...**

```

```

<!-- tabs:end -->