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.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. 例子: 1 ⛽️ 2 ⛽️ 3 ⛽️ 4 ⛽️ 5 ⛽️ 6 ⛽️ 7 ⛽️ 8 ⛽️ 9 ⛽️ 10 放中间, minimized max distance is 0.5 其他情况, 举个最极端的 1 2 3 4 5 ⛽️…⛽️ 6 7 8 9 全部放中间,虽然中间加油站之间的distance 是0.1 ,但是minimized最大的distance 还是1 再举个例子: 1 3 8 K = 3 1 3 ⛽5.5 8 1 3 ⛽5.5 ⛽️6.75 8 1 ⛽️2 3 ⛽️5.5 ⛽️6.75 8 思路:每一次我们选用最大的距离,取中点一分为二。假如需要插入多个加油站,那么均分一段距离可以保证油站之间距离最大 我们可不可以继续借用exam room interval 的方法? Solution 1: 我们把每个油站之间的距离保存到数据结构。每次把最大平均距离的interval 拿出来,再加一个油站。那么这段interval之间的距离就会减小 数据结构:priorityqueue Time: O(KlogN) Space: O(N) -- where n is the length of stations and K is new gas stations to be added public double minmaxGasDist(int[] stations, int K) { if (stations == null || stations.length == 0) return 0.0; PriorityQueue<Interval> maxHeap = new PriorityQueue<>(new Comparator<Interval>(){ @Override public int compare(Interval i1, Interval i2) { return (double)i1.distance/i1.stops < (double)i2.distance/i2.stops ? 1:-11; } }); for (int i = 0; i < stations.length - 1; i++) { maxHeap.offer(new Interval(stations[i + 1] - stations[i], 1)); } while (K > 0) { Interval cur = maxHeap.poll(); cur.stops++; maxHeap.offer(cur); K--; } Interval res = maxHeap.poll(); return (double)res.distance/res.stops; } class Interval { int distance; int stops; public Interval(int distance, int stops) { this.distance = distance; this.stops = stops; } } Solution 2: Binary Search 1.解函数的sorted性质 解空间maximum distance between adjacent gas stations: [1 x 2 x 3 x 4 x 5 x 6 x 7 x x 9 x 10] 0 0.1 0.2 x x x min_distance(0.5) 0.6 0.7 y y y 1.0 其中xxx均是达不到的,yyy均是可实现的 2.函数模型 f(i): 在N个stations之间最多再添加K个stations,使得任意两个stations之间的距离 <= i 吗? 即: f(x) = false f(y) = true 我们要做的就是找到第一个y 3.search range: 确定边界条件 [0, stations[stations.length - 1] - stations[0]] 更准确的是: K = 0的时候,上边界是max(stations[i] - stations[i - 1]), 0 < i < stations.length K = +infinite的时候,下边界趋近于0 mid: 假设我们固定一个mid值 来尝试寻找是否能满足最多添加K个stations,使得任意两个stations之间的距离 <= mid How to narrow the search range without missing correct answer? If the current mid can be a solution, then we search on the lower half, else we search in higher half. (因为f(i)是单调的) 4.check function now the question becomes to how to check if a mid value is feasible or not? 最难的一步 ⇔ sliding window problem 0 1 2 3 4 5 x x x x x x stations[1] - stations[0] = distance case1: distance = mid -> do nothing case2: distance < mid -> do nothing case3: distance > mid -> 需要在station 1和station 0添加多少个stations,才能使得任意两个间的distance <= mid? -> Math.ceil(distance / mid) - 1 ⇔ (int)(distance / mid) Time: O(nlogm) - m the length of max interval Space: O(1) (0, stations[stations.length - 1] - stations[0]) ------------------------------------------ 0 3 7 18 int 32 2^64 public double minmaxGasDist(int[] stations, int K) { if (stations == null || stations.length == 0) return 0.0; double start = 0; double end = stations[stations.length - 1] - stations[0]; double eps = 1e-6; while (start + eps < end) { double mid = start+ (end - start)/2; if (checkFeasible(stations, K, mid)) { end = mid; } else { start = mid; } } return start; } private boolean checkFeasible(int[] stations, int K, double mid) { int count = 0; for (int i = 0; i < stations.length - 1; i++) { count += Math.ceil((stations[i + 1] - stations[i])/mid) - 1; if (count > K) return false; } return true; }
774. Minimize Max Distance to Gas Station
猜你喜欢
转载自www.cnblogs.com/tobeabetterpig/p/9697634.html
今日推荐
周排行