不管全世界所有人怎么说,我都认为自己的感受才是正确的。无论别人怎么看,我绝不打乱自己的节奏。喜欢的事自然可以坚持,不喜欢的怎么也长久不了。
LeetCode:原题地址
题目要求
冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。
在加热器的加热半径范围内的每个房屋都可以获得供暖。
现在,给出位于一条水平线上的房屋 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
思路
- 对供暖器排序
- 遍历房屋,用二分查找找到距离当前房屋最近的左右两边的供暖器
- 左右任意一个供暖器都可以,故当前距离取左右供暖器距离的较小者
- 更新半径,要满足所有房间,故半径取当前距离和旧半径的较大者
const findRadius = (houses, heaters) => {
let r = 0;
heaters.sort((a, b) => a - b);
const n = heaters.length;
for (const house of houses) {
// 距离当前房屋最近的左供暖器i(可重合)
const i = search(heaters, house);
// 右供暖器j
const j = i + 1;
// 计算当前房屋离左右供暖器的距离
const left = i < 0 ? Infinity : house - heaters[i];
const right = j >= n ? Infinity : heaters[j] - house;
// 更新半径
r = Math.max(r, Math.min(left, right));
}
return r;
};
const search = (heaters, house) => {
let [left, right] = [0, heaters.length - 1];
// 最小的供暖器都在目标房屋的右边
// 说明房屋左边没有合适的供暖器,用-1代替
if (heaters[left] > house) return -1;
while (left < right) {
// const mid = (left + right) >> 1;
const mid = ((right - left + 1) >> 1) + left;
if (heaters[mid] > house) {
right = mid - 1;
} else {
left = mid;
}
}
return left;
};