题目
题目来源:力扣(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
思路分析
首先对供暖器位置进行升序排序,然后考察每一栋房子和供暖器的最小距离, 所有最小距离的最大值,就是答案,最小距离可通过房子和最近的两个供暖器距离取小而得到。
// 思考,如何去查找最小路径// 实际上就是去,查找第一个大于等于X的位置,// 假设是房子X,供暖器是a1,a2,a3,a4,a5;a4是大于等于x的,那么前面的a3是小于x的// x是落在a3 和 a4中间的,相当于x落在了查找到位置和前一位的中间值// 那么我们只要判断,这两个值哪一个是距离x最近的就行了var findRadius = function (houses, heaters) {heaters.sort((a, b) => a - b)let ans = 0;for (const x of houses) {//遍历每一个房子的位置let j = binarySearch(heaters, x);//j是第一个大于等于房子位置的,这个二分模型0,1,前面是小于x的,后面的大于等于x的,找到大于等于x的let a = Math.abs(heaters[j] - x);let b = Math.abs(j ? x - heaters[j - 1] : a + 1);//j 位置前面有多少元素ans = Math.max(ans, Math.min(a, b));//当前x的房子的供暖器的半径最近就是a,b之间的较小值}return ans;};var binarySearch = function (nums, x) {let head = 0, tail = nums.length - 1, mid;while (head < tail) {//当头尾坐标不重合mid = (head + tail) >> 1;if (nums[mid] >= x) tail = mid;//else head = mid + 1;}return head;}// 理解这个程序,有可能返回的是大于等于x的,有可能返回的是数组的最后一个// 那么这个写法呢,就会在合法范围内,尽量返回大于等于X的位置,如果不能返回,就返回小于X的位置
