「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」
题目
冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。
在加热器的加热半径范围内的每个房屋都可以获得供暖。
现在,给出位于一条水平线上的房屋 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步,对房子数组和供暖器数组排序
- 枚举房子数组,对任意房子 寻找其距离最近的供暖器
- 假设房子所在的位置为
- 供暖器排序数组
- 寻找房子 在排序数组 插入的位置,是不是就找到了距房子最近的供暖器了
- 排序数组寻找目标值插入位置,典型的二分法, 参考搜索插入位置
- 找到插入位置后需要对特殊位置处理
- 假设插入位置为0,说明房子之前没有供暖器
- 假设插入位置大于len-1,说明房子之后没有供暖器
- 其他位置,插入位置供暖器与插入位置的前一个供暖器构成距房子最近的供暖器,取二者较小值
- 获取所有房屋供暖最小半径的最大值
- 返回结果
根据上述思路编辑代码如下:
代码
var findRadius = function (houses, heaters) {
// 排序
houses.sort((a, b) => a - b)
heaters.sort((a, b) => a - b)
// 排序后,房子要么使用前一个供暖器,要么使用后一个供暖器
// 供暖器数量
const len = heaters.length
let result = 0
for (let i = 0; i < houses.length; i++) {
// 第K间房子,根据房子找最近的灯
const k = houses[i]
let left = 0
let right = len - 1
while (left <= right) {
const m = (left + right) >> 1
if (heaters[m] === k) {
left = m
break
}
if (heaters[m] < k) {
left = m + 1
} else {
right = m - 1
}
}
if (heaters[left] === k) continue
// 第一个,
if (left === 0) {
const after = Math.abs(heaters[left] - k)
result = Math.max(result, after)
} else if (left > len - 1) {
const after = Math.abs(heaters[len - 1] - k)
result = Math.max(result, after)
} else {
const after = Math.abs(heaters[left] - k)
const next = Math.abs(heaters[left - 1] - k)
result = Math.max(result, Math.min(after, next))
}
}
return result
}