Description
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.
Solution
给一个数组,数组中的数字是0 - arr.length的排列,问最多能把这个数组分割成几块儿,使得把每一块排序之后,形成完整的排序数组。
**Approach 1 **: binary search
Now we are using binary search to find the smallest possible value of D. Using the hint 1e-6 error will be accepted.
I initilze left = 0 and right = the distance between the first and the last station
count is the number of gas station we need to make it possible.
if count > K, it means mid is too small to realize using only K more stations.
if count <= K, it means mid is possible and we can continue to find a bigger one.
When left + 1e-6 >= right, it means the answer within 10^-6 of the true value and it will be accepted.
My understanding for count+= Math.ceil((st[i + 1] - st[i]) / mid) - 1:
if we are to have mid as the max min distance between any two buildings, this count is how many more houses can we add to the array.
and we can compute this count by trying to inserting new houses between the 2 adjacent houses.
for any 2 adjacent houses, we divide their original distance by the min distance (mid) we could have in the array, to try to insert as many houses as we can into any 2 adjacent houses.
this step is computing the number of houses we can insert into this original array.
Code
class Solution {
public double minmaxGasDist(int[] stations, int K) {
int count = 0, n = stations.length;
double left = 0, right = stations[n - 1] - stations[0], mid = 0;
while (left + 1e-6 < right){
mid = (left + right) / 2;
count = 0;
for (int i = 0; i < n - 1; i++){
count += Math.floor((stations[i + 1] - stations[i]) / mid);
}
if (count > K){
left = mid;
}
else{
right = mid;
}
}
return left;
}
}
Time Complexity: O(NlogM), where N is stations length and M is st[N - 1] - st[0]
Space Complexity: O(1)
Review
Approach 2: Priority Queue
class Solution {
public double minmaxGasDist(int[] stations, int K) {
Arrays.sort(stations);
PriorityQueue<Interval> que = new PriorityQueue<Interval>(new Comparator<Interval>() {
public int compare(Interval a, Interval b) {
double diff = a.distance() - b.distance();
if (diff < 0) { return +1; }
else if (diff > 0) { return -1; }
else { return 0; }
}
});
double leftToRight = stations[stations.length-1] - stations[0];
int remaining = K;
for (int i = 0; i < stations.length-1; i++) {
int numInsertions = (int)(K*(((double)(stations[i+1]-stations[i]))/leftToRight));
que.add(new Interval(stations[i], stations[i+1], numInsertions));
remaining -= numInsertions;
}
while (remaining > 0) {
Interval interval = que.poll();
interval.numInsertions++;
que.add(interval);
remaining--;
}
Interval last = que.poll();
return last.distance();
}
class Interval {
double left;
double right;
int numInsertions;
double distance() { return (right - left)/ ((double)(numInsertions+1)) ; }
Interval(double left, double right, int numInsertions) { this.left = left; this.right = right; this.numInsertions = numInsertions; }
}
}