LWC 69: 774. Minimize Max Distance to Gas Station
傳送門:774. Minimize Max Distance to Gas Station
Problem:
On a horizontal number line, we have gas stations at positions stations[0], stations1, …, stations[N-1], where N = stations.length.
Now, we add K more gas stations so that D, the maximum distance between adjacent gas stations, is minimized.
Return the smallest possible value of D.
Example:
Input: stations = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], K = 9
Output: 0.500000
Note:
- stations.length will be an integer in range [10, 2000].
- stations[i] will be an integer in range [0, 10^8].
- K will be an integer in range [1, 10^6].
- Answers within 10^-6 of the true value will be accepted as correct.
思路:
首先求出每個station之間的距離,考慮如下問題:兩個station爲[1, 9],gap爲8。要插入一個station使得最大的最小,顯然插入後應該爲[1, 5, 9],最大間隔爲4。舉個反例,如果插入後爲[1, 6, 9], [1, 3, 9],它們的最大間隔分別爲5, 6,明顯不是最小。從這裏可以看出,對於插入k個station使得最大的最小的唯一辦法是均分。
一種貪心的做法是,找到最大的gap,插入1個station,依此類推,但很遺憾,這種貪心策略是錯誤的。問題的難點在於我們無法確定到底哪兩個station之間需要插入station,插入幾個station也無法得知。
換個思路,如果我們假設知道了答案會怎麼樣?因爲知道了最大間隔,所以如果目前的兩個station之間的gap沒有符合最大間隔的約束,那麼我們就必須添加新的station來讓它們符合最大間隔的約束,這樣一來,對於每個gap我們是能夠求得需要添加station的個數。如果需求數<=K,說明我們還可以進一步減小最大間隔,直到需求數>K。
Java版本:
public double minmaxGasDist(int[] stations, int K) {
int n = stations.length;
double[] gap = new double[n - 1];
for (int i = 0; i < n - 1; ++i) {
gap[i] = stations[i + 1] - stations[i];
}
double lf = 0;
double rt = Integer.MAX_VALUE;
double eps = 1e-7;
while (Math.abs(rt - lf) > eps) {
double mid = (lf + rt) /2;
if (check(gap, mid, K)) {
rt = mid;
}
else {
lf = mid;
}
}
return lf;
}
boolean check(double[] gap, double mid, int K) {
int count = 0;
for (int i = 0; i < gap.length; ++i) {
count += (int)(gap[i] / mid);
}
return count <= K;
}
Python版本:
class Solution(object):
def minmaxGasDist(self, st, K):
"""
:type stations: List[int]
:type K: int
:rtype: float
"""
lf = 1e-6
rt = st[-1] - st[0]
eps = 1e-7
while rt - lf > eps:
mid = (rt + lf) / 2
cnt = 0
for a, b in zip(st, st[1:]):
cnt += (int)((b - a) / mid)
if cnt <= K: rt = mid
else: lf = mid
return rt