这是我参与2022首次更文挑战的第15天,活动详情查看: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
思路
- 我们可以对房屋和供暖器先做一轮排序,然后对于每个房屋,要么用前面的暖气,要么用后面的,二者取近的,得到距离;
- 一开始我们的半径是0,当我们的最近距离大于我们的半径的时候,我们的半径要扩大成当前的最近距离;
- 我们可以通过一轮遍历,每次判断房屋是离当前的供暖器比较近还是下一个比较近,同时我们用一个索引
hIndex来记录我们当前用的是哪个供暖器; - 最终遍历结束后我们统计出来的结果就是最小值了。
实现
/**
* @param {number[]} houses
* @param {number[]} heaters
* @return {number}
*/
var findRadius = function(houses, heaters) {
// 先对两个数组分别进行排序
houses.sort((a, b) => a - b);
heaters.sort((a, b) => a - b);
// 然后用贪心算法,判断当前房子离这个供暖器和下个供暖器的最近距离
// 如果最小值大于我们的半径,那么半径变成新的最小值
let hIndex = 0; // 记录供暖器的位置
let r = 0; // 半径的长度
// 枚举所有的房屋
for (let i = 0; i < houses.length; i++) {
// 如果后面还有供暖器, 并且后面的供暖器近就把供暖器的位置往后移动一个位置
if (hIndex < heaters.length - 1
&& Math.abs(heaters[hIndex + 1] - houses[i]) < Math.abs(heaters[hIndex] - houses[i])) {
hIndex++;
}
// 这里不能简写,因为我们不确定是否拥有heaters[hIndex + 1],这个值会变化的
r = Math.max(r, Math.abs(heaters[hIndex] - houses[i]));
}
return r;
};
翻车
分析原因,为什么我们算出来的答案跟实际的不相符。其实是因为我们这样子统计,只能比较当前的供暖器和下一个供暖器之间的大小关系,实际上我们需要比较的是后面所有比之大的,所以这个地方我们不能用if来单纯判断当前和下一个,而是要用while来不断做判断直到找到为止。
最终代码
/**
* @param {number[]} houses
* @param {number[]} heaters
* @return {number}
*/
var findRadius = function(houses, heaters) {
// 先对两个数组分别进行排序
houses.sort((a, b) => a - b);
heaters.sort((a, b) => a - b);
// 然后用贪心算法,判断当前房子离这个供暖器和下个供暖器的最近距离
// 如果最小值大于我们的半径,那么半径变成新的最小值
let hIndex = 0; // 记录供暖器的位置
let r = 0; // 半径的长度
// 枚举所有的房屋
for (let i = 0; i < houses.length; i++) {
// 如果后面还有供暖器, 并且后面的供暖器近就把供暖器的位置往后移动一个位置
while (hIndex < heaters.length - 1
&& Math.abs(heaters[hIndex + 1] - houses[i]) <= Math.abs(heaters[hIndex] - houses[i])) {
hIndex++;
}
r = Math.max(r, Math.abs(heaters[hIndex] - houses[i]));
}
return r;
};
结果
看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。