leetCode每日一题js--01供暖器

供暖器

题目:

在加热器的加热半径范围内的每个房屋都可以获得供暖。

现在,给出位于一条水平线上的房屋 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

问题转化:

一个房屋需要的供暖器的最小加热半径 = 离该房屋最近的供暖器

max{每个房屋需要的供暖器的最小加热半径}=可以覆盖所有房屋的最小加热半径。

如何计算离该房屋最近的供暖器?

请添加图片描述

解题思路:

思路一:暴力求解

每个房屋都去遍历供暖器,计算自己与供暖器的距离,保存最小值存起来。

在所有的房屋的距离中找最小值。

复杂度很高,O(m*n)

思路二:不要遍历查找,要二分查找

m*log(n)+nlog(n)[数组排序]

复杂度O((m+n)*log(n))

二分查找:先排序,再二分查找,找到最小的距离,然后记录下来。

思路三:二分查找的边界值很难确定,因此可以使用双指针,思路清晰。

对于每个房屋:

  • 当前房间有供暖器,这是我们就选当前位置为0

  • 右边最近:heaters[i] - house

  • 左边最近:house - heaters[i]

  • 特殊情况:房子左边没有暖气,(即房子位于最左边);右边没暖气。

将房子和暖气都进行排序。

对于每个房子:i指针用于遍历房子

找最小距离,就是指针 j 在暖气上移动,移到大于房子的暖气(在房子右边)则停下,这是离房子最近的右边的暖气

指针j -1:就是左边的离房子最近的暖气。

对于房子i:d = min (house[i]-heaters[j],house[i]-heaters[j-1])

var findRadius = function(houses, heaters) {
    
    // 将房子和暖气都进行排序。
    houses.sort((a, b) => a - b);
    heaters.sort((a, b) => a - b);
    
    let ans = 0;
    for (let i = 0, j = 0; i < houses.length; i++) {
        while (j < heaters.length && heaters[j] < houses[i]){
            j++;
        }
        
        let curDistance = Math.abs(houses[i] - heaters[j]);
        if(j === 0){
           curDistance = heaters[0]-houses[i] ;
        }else if(j === heaters.length){
            curDistance = houses[i]-heaters[heaters.length-1];
        }else {
            curDistance = Math.min(Math.abs(houses[i] - heaters[j-1]), Math.abs(houses[i] - heaters[j]));
        }
  
        ans = Math.max(ans, curDistance);
    }
    return ans;
};

细节优化处理:提交了两次,一次打败80%,一次打败94%。

优化的点在于 将length 赋给一个变量,这样就只需要计算一次数组的长度。

/**
 * @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 ans = 0;

    for (let i = 0, j = 0; i < houses.length; i++) {
        while (j < heaters.length && heaters[j] < houses[i]){
            j++;
        }

        let curDistance = Math.abs(houses[i] - heaters[j]);
        // 
        let len = heaters.length;
        if(j === 0){
           curDistance = heaters[0]-houses[i] ;
        }else if(j === len){
            curDistance = houses[i]- heaters[len-1];
        }else {
            curDistance = Math.min(Math.abs(houses[i] - heaters[j-1]), curDistance);
        }

        ans = Math.max(ans, curDistance);
    }
    return ans;
};
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凭栏听雨客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值