冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。
在加热器的加热半径范围内的每个房屋都可以获得供暖。
现在,给出位于一条水平线上的房屋 houses 和供暖器 heaters 的位置,请你找出并返回可以覆盖所有房屋的最小加热半径。
说明 :所有供暖器都遵循你的半径标准,加热的半径也一样。

示例 1:

  1. 输入: houses = [1,2,3], heaters = [2]
  2. 输出: 1
  3. 解释: 仅在位置2上有一个供暖器。如果我们将加热半径设为1,那么所有房屋就都能得到供暖。

示例 2:

输入: houses = [1,2,3,4], heaters = [1,4]
输出: 1
解释: 在位置1, 4上有两个供暖器。我们需要将加热半径设为1,这样所有房屋就都能得到供暖。

示例 3:

输入:houses = [1,5], heaters = [2]
输出:3

提示:

  • 1 <= houses.length, heaters.length <= 3 * 10^4
  • 1 <= houses[i], heaters[i] <= 10^9

解法一:二分法

func findRadius(houses []int, heaters []int) int {
    sort.Ints(heaters)
    n := len(heaters)
    res := 0
    for _, house := range houses {
        idx := binarySearch(heaters, house)
        var dis int
        if idx < 0 {
            // 没有比 house 更大的值了
            dis = house - heaters[n-1]
        } else if idx == 0 {
            // 第一个值都比 house 大
            dis = heaters[0] - house
        } else {
            dis = min(heaters[idx]-house, house-heaters[idx-1])
        }
        res = max(res, dis)
    }
    return res
}

// 第一个大于等于 target 的值
func binarySearch(nums []int, target int) int {
    left, right := 0, len(nums)-1
    for left <= right {
        mid := left + (right-left)>>1
        if nums[mid] >= target {
            if mid == 0 || nums[mid-1] < target {
                return mid
            }
            right = mid - 1
        } else {
            left = mid + 1
        }
    }
    return -1
}

func max(x, y int) int {
    if x > y {
        return x
    }
    return y
}

func min(x, y int) int {
    if x > y {
        return y
    }
    return x
}