【我也想刷穿 LeetCode啊】475. 供暖器

80 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

现在前端很多岗位面试需要有一定的算法基础,或者说经常刷算法的会优先考虑。

因此每天刷刷LeetCode非常有必要

在这之前我也刷过一些算法题,也希望以后也坚持刷,跟某掘友一样,我也想刷穿 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

二、思路分析

第一步以每一个房屋为研究中心,然后遍历加热站(可以利用二分法节省效率)找到房屋的前一个加热站和后一个加热站。 接着通过比较房屋和前后加热站的距离比较房屋和谁更近。

对于所有房屋h(1),h(2),h(3)···h(n),每个房屋与最近的加热站的距离为dis(n),n为房间编号。即每个房屋距离加热站 的最短距离disList为: disList=[dis(1),dis(2),dis(3)···dis(n)] 因此: 当取disList中的最大值dis-max时。一定满足dis-max大于等于disList中的每一项。即dis-max一定能够辐射到每一个房屋。 为此dis-max即为问题的解。

三、代码实现



/**
 * @param {number[]} houses
 * @param {number[]} heaters
 * @return {number}
 */
function add(val1, val2) {
    return val1 - val2
}
var findRadius = function (houses, heaters) {
    //先对输入数据进行排序,以免数据无顺序二分法出错
    houses.sort(add)
    heaters.sort(add)
    let dis_max = 0
    for (let i = 0; i < houses.length; i++) {
        let left = 0
        let right = heaters.length - 1
        //如果right - left===1 就说明了房屋处已经于加热站left和加热站right中间。因此不用在遍历了
        while ((right - left) > 1) {
            //找到处于中间位置的加热站。这时有三种情况
            //1、如果mid位置上的加热站的值等于此时所迭代到的房屋。那么就不用往下查找加热站。直接令left等于right等于mid退出循环即可
            //2、如果mid位置上加热站的值大于此时所跌倒到的房屋。那么就说明房屋处于二分后的左半部分。这时令right等于mid继续循环
            //3、如果mid位置上的加热站的值小于此时所迭代的房屋。那么说明此时房屋位于二分后的右半部分。这时令left等于mid继续查找房屋的前后加热站
            let mid = Math.floor((left + right) / 2)
            if (heaters[mid] === houses[i]) {
                left=mid
                right=mid
            } else if (heaters[mid] > houses[i]) {
                right = mid
            } else if (heaters[mid] < houses[i]) {
                left = mid
            }
        }
        //找到了房屋i的前后加热站那leftright后。通过计算房屋距离前后加热站的最短距离来判断是否要更新dis_max的值
        let max = Math.abs(houses[i] - heaters[left]) > Math.abs(houses[i] - heaters[right]) ? Math.abs(houses[i] - heaters[right]) : Math.abs(houses[i] - heaters[left])
        dis_max = max > dis_max ? max : dis_max
    }
    return dis_max
};

四、总结

以上就是本道题的所有内容了,本系列会持续更,欢迎点赞、关注、收藏,另外如有其他的问题,欢迎下方留言给我,我会第一时间回复你,感谢~