「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」
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
提示:
1 <= houses.length, heaters.length <= 3 * 1041 <= houses[i], heaters[i] <= 109
排序+二分查找
思路
由题意可知,我们需要求出满足供暖需求的最小半径
其实需要我们求每个房子距离最近的供暖器的最大距离
为了方便查找距离每个房子最近的供暖期的位置,我们这里将供暖期的数组进行排序,然后就可以用二分查找的方式,快速定位供暖期的位置
- 房子的左右都有供暖器,那么我们需要比较两个供暖器的具体,找出最进的供暖期
- 房子只有右边有供暖器,那么这就是距离房子最近的供暖期,题目中为了方便查找位置,将左边的距离设置为无穷大
- 房子只有左边有供暖器,那么这就是距离房子最近的供暖期,题目中为了方便查找位置,将右边边的距离设置为无穷大
具体实现:
- 对heaters进行sort排序
- 遍历houses,用findNear函数查找每个房子左侧的供暖期下标left,右侧供暖器下标为left+1
- 如果房子左侧没有供暖器,那么left = -1,right = 0,最小距离为item-heaters[left]
- 如果房子左右都有供暖器,那么left和right正常计算,最小距离为item-heaters[left]和heaters[right] - item取最小值
- 如果房子右侧没有供暖器,那么left = heaters.length - 1,right = heaters.length,最小距离为heaters[right] - item
- 得到每个房子的最后距离后,取最大值保存在res中
最后返回res即可
var findRadius = function (houses, heaters) {
let res = 0;
heaters.sort((a, b) => a - b);
for (var i = 0; i < houses.length; i++) {
var item = houses[i]
var left = findNear(heaters, item);
var right = left + 1
var leftDistance = left < 0 ? Number.MAX_VALUE : item - heaters[left];
var rightDistance = right >= heaters.length ? Number.MAX_VALUE : heaters[right] - item;
var minDistance = Math.min(leftDistance, rightDistance);
res = Math.max(res, minDistance);
}
return res;
};
var findNear = (nums, target) => {
let start = 0, end = nums.length - 1;
if (nums[start] > target) {
return -1;
}
while (start < end) {
var mid = Math.ceil((start + end) /2);
if (nums[mid] > target) {
end = mid - 1;
} else {
start = mid;
}
}
return start;
}