二分供暖器

Posted FatalFlower

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分供暖器相关的知识,希望对你有一定的参考价值。

对应 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/

以上是关于二分供暖器的主要内容,如果未能解决你的问题,请参考以下文章

leetcode 工作每日一题 475. 供暖器 (二分 stl)

leetcode 工作每日一题 475. 供暖器 (二分 stl)

leetcode 475. 供暖器(Heaters)

LeetCode刷题供暖器:妙解

《LeetCode之每日一题》:244.供暖器

Leetcode 475.供暖气