ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二分(二)供暖器

2021-12-20 10:03:23  阅读:177  来源: 互联网

标签:二分 heaters 供暖 覆盖 int houses 半径


对应 LeetCode 475.供暖器

问题描述

给出位于一条水平线上的房屋 \(houses\) 和供暖器 \(heaters\) 的位置,请找出并返回可以覆盖所有房屋的最小加热半径。所有供暖器都遵循你的半径标准,加热的半径也一样

比如,对于输入的 \(house=[1, 5]\)​,\(heaters=[2]\)​,那么至少需要使得供暖器的最小覆盖半径为 3 才能使得所有\(house\)​​​ 都能够被供暖器覆盖

数据范围:

  • \(1 <= houses.length, heaters.length <= 3 * 10^4\)​

  • \(1 <= houses[i], heaters[i] <= 10^9\)​

解决思路

由题目描述可知,本题具备的二分性:

  • 如果供暖器的覆盖半径足够大,那么肯定能够将所有的房子都覆盖
  • 如果供暖器的半径过小,那么肯定存在房子无法被覆盖

可以考虑通过二分的方式来求得最小的覆盖半径。二分的最小值为 0,即每个房子都有自己的供暖器,此时就不再需要覆盖半径;二分的最大值为 \(houses\) 的最大值,为了简单起见,可以将最大值设为 \(10^9\)

现在关键的地方在于如何检查给定的半径是否能够覆盖所有的房子。首先,需要对 \(houses\) 和 \(heaters\) 进行排序,然后再遍历 \(houses\) 的每个元素,找到在当前半径的条件下能够覆盖该 \(house\) 的最小的供暖器,如果无法找到,那么说明无法覆盖该 \(house\)

实现

具体的实现如下:

class Solution {
    public int findRadius(int[] houses, int[] heaters) {
        Arrays.sort(houses);
        Arrays.sort(heaters);

        int lo = 0, hi = (int) 1e9;
        // 注意二分的边界情况,这是一个细节性的问题
        while (lo < hi) {
            int mid = lo + ((hi - lo) >> 1);
            if (check(houses, heaters, mid)) hi = mid;
            else lo = mid + 1;
        }

        return hi;
    }

    boolean check(int[] houses, int[] heaters, int x) {
        int n = houses.length, m = heaters.length;
        /*
        	通过双指针的方式首先找到合适的供暖器 heaters[j],
        	然后再使用当前的覆盖半径检测是否能够覆盖该房子
        */
        for (int i = 0, j = 0; i < n; ++i) {
            while (j < m && heaters[j] + x < houses[i]) ++j;
            // j >= m 说明没有供暖器了
            if (j < m && houses[i] >= heaters[j] - x && houses[i] <= heaters[j] + x) 
                continue;
            return false;
        }

        return true;
    }
}

时间复杂度:令 \(n=house.length, m = heaters.length\),排序带来 \(O(nlog_2n) + O(mlog_2m)\) 的时间复杂度,使用二分搜索带来的时间复杂度为 \(O(nlog_210^9)\) 总体时间复杂度为 \(O(max(n, m)*log_210^9)\)

空间复杂度:具体由排序算法带来的空间复杂度,在这里不做分析

参考:https://leetcode-cn.com/problems/heaters/solution/gong-shui-san-xie-er-fen-shuang-zhi-zhen-mys4/

标签:二分,heaters,供暖,覆盖,int,houses,半径
来源: https://www.cnblogs.com/FatalFlower/p/15709603.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有