[LeetCode] 774. Minimize Max Distance to Gas Station 最小化加油站间的最大距离
On a horizontal number line, we have gas stations at positions stations[0], stations[1], ..., 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.lengthwill be an integer in range[10, 2000].stations[i]will be an integer in range[0, 10^8].Kwill be an integer in range[1, 10^6].- Answers within
10^-6of the true value will be accepted as correct.
思路:首先如何使得每个station之间的最大距离最小,比如:两个station为[1, 9],间隔为8。要插入一个station使得最大距离最小,插入后应该为[1, 5, 9],最大间隔为4。如果插入后为[1, 6, 9], [1, 3, 9],它们的最大间隔分别为5, 6,不是最小。可以看出,对于插入k个station使得最大间隔最小的唯一办法是均分。
一种贪心的做法是,找到最大的gap,插入1个station,依此类推,但很遗憾,这种贪心策略是错误的。问题的难点在于我们无法确定到底哪两个station之间需要插入station,插入几个station也无法得知。用DP会内存超标MLE,用堆会时间超标TLE。
换个思路,如果假设知道了答案会怎么样?因为知道了最大间隔,所以如果目前的两个station之间的gap没有符合最大间隔的约束,就必须添加新的station来让它们符合最大间隔的约束,这样对于每个gap能够求得需要添加station的个数。如果需求数<=K,说明还可以进一步减小最大间隔,直到需求数>K。
解法1: 优先队列,每次找出gap最大的一个区间,然后新加入一个station,直到所有的k个station都被加入,此时最大的gap即为所求。采用优先队列,使得每次最大的gap总是出现在队首。空间复杂度是O(n),时间复杂度是O(klogn),其中k是要加入的新station的个数,n是原有的station个数。这种方法应该没毛病,但是TLE
解法:二分法,判定条件不是简单的大小关系,而是根据子函数。minmaxGap的最小值left = 0,最大值right = stations[n - 1] - stations[0]。每次取mid为left和right的均值,然后计算如果mimaxGap为mid,那么最少需要添加多少个新的stations,记为count。如果count > K,说明均值mid选取的过小,必须新加更多的stations才能满足要求,更新left的值;否则说明均值mid选取的过大,使得需要小于K个新的stations就可以达到要求,寻找更小的mid,使得count增加到K。如果假设stations[N- 1] - stations[0] = m,空间复杂度是O(1),时间复杂度是O(nlogm),可以发现与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, stations, K):
"""
:type stations: List[int]
:type K: int
:rtype: float
"""
def possible(stations, K, guess):
return sum(int((stations[i+1]-stations[i]) / guess)
for i in xrange(len(stations)-1)) <= K left, right = 0, 10**8
while right-left > 1e-6:
mid = left + (right-left)/2.0
if possible(mid):
right = mid
else:
left = mid
return left
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
Python:
class Solution(object):
def minmaxGasDist(self, stations, K):
"""
:type stations: List[int]
:type K: int
:rtype: float
"""
stations.sort()
step = 1e-9
left, right = 0, 1e9
while left <= right:
mid = (left + right) / 2
if self.isValid(mid, stations, K):
right = mid - step
else:
left = mid + step
return mid
def isValid(self, gap, stations, K):
for x in range(len(stations) - 1):
dist = stations[x + 1] - stations[x]
K -= int(math.ceil(dist / gap)) - 1
return K >= 0
C++:
class Solution {
public:
double minmaxGasDist(vector<int>& stations, int K) {
double left = 0, right = 1e8;
while (right - left > 1e-6) {
double mid = left + (right - left) / 2;
if (helper(stations, K, mid)) right = mid;
else left = mid;
}
return left;
}
bool helper(vector<int>& stations, int K, double mid) {
int cnt = 0, n = stations.size();
for (int i = 0; i < n - 1; ++i) {
cnt += (stations[i + 1] - stations[i]) / mid;
}
return cnt <= K;
}
};
C++:
class Solution {
public:
double minmaxGasDist(vector<int>& stations, int K) {
double left = 0, right = 1e8;
while (right - left > 1e-6) {
double mid = left + (right - left) / 2;
int cnt = 0, n = stations.size();
for (int i = 0; i < n - 1; ++i) {
cnt += (stations[i + 1] - stations[i]) / mid;
}
if (cnt <= K) right = mid;
else left = mid;
}
return left;
}
};
类似题目:
719. Find K-th Smallest Pair Distance
668. Kth Smallest Number in Multiplication Table
644. Maximum Average Subarray II
378. Kth Smallest Element in a Sorted Matrix
All LeetCode Questions List 题目汇总
[LeetCode] 774. Minimize Max Distance to Gas Station 最小化加油站间的最大距离的更多相关文章
- [LeetCode] Minimize Max Distance to Gas Station 最小化去加油站的最大距离
On a horizontal number line, we have gas stations at positions stations[0], stations[1], ..., statio ...
- LeetCode - 774. Minimize Max Distance to Gas Station
On a horizontal number line, we have gas stations at positions stations[0], stations[1], ..., statio ...
- LC 774. Minimize Max Distance to Gas Station 【lock,hard】
On a horizontal number line, we have gas stations at positions stations[0], stations[1], ..., statio ...
- leetcode 刷题之路 68 Gas Station
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...
- 贪心:leetcode 870. Advantage Shuffle、134. Gas Station、452. Minimum Number of Arrows to Burst Balloons、316. Remove Duplicate Letters
870. Advantage Shuffle 思路:A数组的最大值大于B的最大值,就拿这个A跟B比较:如果不大于,就拿最小值跟B比较 A可以改变顺序,但B的顺序不能改变,只能通过容器来获得由大到小的顺 ...
- [LeetCode] Gas Station
Recording my thought on the go might be fun when I check back later, so this kinda blog has no inten ...
- leetcode@ [134] Gas station (Dynamic Programming)
https://leetcode.com/problems/gas-station/ 题目: There are N gas stations along a circular route, wher ...
- [LeetCode] Gas Station,转化为求最大序列的解法,和更简单简单的Jump解法。
LeetCode上 Gas Station是比较经典的一题,它的魅力在于算法足够优秀的情况下,代码可以简化到非常简洁的程度. 原题如下 Gas Station There are N gas stat ...
- [LeetCode] Gas Station 加油站问题
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...
随机推荐
- Python开发应用-正则表达进行排序搜索
re模块提供了3个方法对输入的字符串进行确切的查询,match和search最多只会返回一个匹配条件的子串,可以理解为非贪婪模式,而findall会返回N个匹配条件的子串,可以理解为贪婪模式 re.m ...
- PS——使用切片工具切出透明图片
前言 最近有点烦,不说话~ 步骤 首先要保证您的格式为PSD且底色为透明 参考线 标出参考线,方便后面划分 切图 保存 效果
- makefile的三个变量
“$@”代表目标文件. “$^”代表所有的依赖文件. “$<”代表第一个依赖文件. main:main.o mytool1.o mytool2.o gcc -o $@ $^ .c.o: gcc ...
- TreeMap 的简单解释
TreeMap的构造函数 可以传入 自定义的比较器.Map.SortedMap. put方法: public V put(K key, V value) { Entry<K,V> ...
- 002-官网安装openstack之-安装基础服务
安装openstack基础服务 1.控制节点安装时间同步服务(chrony) (1)时间同步大体来说有两种方式: 一种是自己搭建时间同步服务器,各个需要同步时间的节点,与其同步时间 另一种则是使用nt ...
- janusgraph单机版安装
注:本次安装janusgraph基于es和hbse,所以先安装es和hbase 1.安装jdk 2.安装janusgraph 解压安装文件至/usr/janusgraph-0.3.1 unzip ja ...
- 解决最新版fitnesse无法运行测试用例的问题
用fitnesse-standalone.jar这个jar包时 运行测试用例会报错,显示IOException:can not run program:”c:\program files\java\j ...
- PostGraphile 4.4 发布,支持real time 查询
在4.4 之前,real time 是通过插件完成处理的,4.4 直接内置了,还是很方便的功能,总算 和其他类似graphql 平台看齐了,使用上还是挺方便的. 参考资料 https://www.gr ...
- 2019SDSC夏令营游记
Day 1 2019.7.22 晴 第一天夏令营,是在一所大学举办的. 到之前的我好兴奋,要提前看一下大学到底是什么样的. 聊了一上午的天 坐了一上午的公交终于到了目的地,下午很自由,自己在宿舍里面休 ...
- POJ 1741.Tree and 洛谷 P4178 Tree-树分治(点分治,容斥版) +二分 模板题-区间点对最短距离<=K的点对数量
POJ 1741. Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 34141 Accepted: 11420 ...