475. 供暖器
冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。
在加热器的加热半径范围内的每个房屋都可以获得供暖。
现在,给出位于一条水平线上的房屋 houses 和供暖器 heaters 的位置,请你找出并返回可以覆盖所有房屋的最小加热半径。
说明:所有供暖器都遵循你的半径标准,加热的半径也一样。
示例 1:
输入: houses = [1,2,3], heaters = [2]
输出: 1
解释: 仅在位置2上有一个供暖器。如果我们将加热半径设为1,那么所有房屋就都能得到供暖。
示例 2:
输入: houses = [1,2,3,4], heaters = [1,4]
输出: 1
解释: 在位置1, 4上有两个供暖器。我们需要将加热半径设为1,这样所有房屋就都能得到供暖。
示例 3:
输入: houses = [1,5], heaters = [2]
输出: 3
解题思路:这题的解题思路就是找到每个房间左边和右边的供暖器,取小值,然后取比较每个房间的最小值,取最大就是最小半径,代码如下:
var findRadius = function(houses, heaters) {
//取暖器房间从小到大排序
heaters.sort((a,b) => {
return a - b;
})
let ans = 0,j,r,l;
//遍历每个房间找到左右两边的取暖器
for(let i = 0; i < houses.length; i ++){
//获得距离房间最近的取暖器,可能是左边也可能是右边,所以取绝对值
j = find_radius(heaters,houses[i]);
r = Math.abs(heaters[j] - houses[i]);
//j如果存在,说明j前面还有值,就可以计算,如果当前房间不存在右边房间,j等于暖暖器最后一个房间,就是左边取暖去,j - 1个取暖器距离当前房间更远,如果j不存在让l比r大就好,因为我吗要取的是小值
l = j ? houses[i] - heaters[j - 1] : r + 1;
ans = Math.max(ans,Math.min(r,l));
}
return ans;
};
let find_radius = function(data,x){
let head = 0,tail = data.length - 1,m;
while(head < tail){
m = (head + tail) >> 1;
if(data[m] < x) head = m + 1;
else tail = m;//因为要找的是大于等于x的值,所以tail 不能等于 m - 1,因为可能会出现,刚好m大于x, m - 1 小于x,这个时候找的就不准了。
}
//如果不存在大于x的值就返回data最大值
return tail;
}