0
点赞
收藏
分享

微信扫一扫

力扣 774. 最小化去加油站的最大距离 二分答案


774. 最小化去加油站的最大距离

整数数组 ​​stations​​ 表示 水平数轴 上各个加油站的位置。给你一个整数 ​​k​​ 。

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

设 ​​penalty()​​​ 是:增设 ​​k​​ 个新加油站后,相邻 两个加油站间的最大距离。

请你返回 ​​penalty()​ 可能的最小值。与实际答案误差在 ​​10-6​​ 范围内的答案将被视作正确答案。


示例 1:

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

示例 2:

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


提示:

  • ​10 <= stations.length <= 2000​
  • ​0 <= stations[i] <= 10^8​
  • ​stations​​ 按严格递增顺序排列
  • ​1 <= k <= 10^6​

做题结果

成功,二分答案,大概 log(1e8)*2e3,合起来大概1e7。 写之前想过贪心,只在最大的元素中间插入加油站。但是如果一个距离中间需要插入多个加油站的情况,就不太好处理了。然后肯定要用到堆。但是用堆的话,和k的关系就比较大了。1e6的nlogn显然超了,不行。如果这题k值很小(1e5的话),就可以堆+贪心过了。

方法:二分答案

1. 最小值估算为0

2. 最大值估算为最大最小的差

3. 二分大概猜一下间距。

4. 两个加油站间距离超过间距的补加油站,如果提供的k个加油站能够补完所有空隙,使得任意两个相邻加油站间的距离小于目标则返回

class Solution {
public double minmaxGasDist(int[] stations, int k) {
int n = stations.length;
double min = 0;
double max = stations[n-1]-stations[0];
while(min+(1.0/1e6)<max){
double mid = (max-min)/2+min;
if(check(stations,mid,k)){
max = mid;
}else{
min = mid;
}
}

return min;
}

private boolean check(int[] stations, double dis,int num){
int n = stations.length;
for(int i = 0; i < n-1&&num>=0; i++){
num-=(int)((stations[i+1]-stations[i])/dis);
}
return num>=0;
}
}

举报

相关推荐

0 条评论