LC475 - Heaters

Description

Winter is coming! During the contest, your first job is to design a standard heater with a fixed warm radius to warm all the houses.

Every house can be warmed, as long as the house is within the heater’s warm radius range.

Given the positions of houses and heaters on a horizontal line, return the minimum radius standard of heaters so that those heaters could cover all houses.

Notice that all the heaters follow your radius standard, and the warm radius will the same.

Example 1:

Input: houses = [1,2,3], heaters = [2]
Output: 1
Explanation: The only heater was placed in the position 2, and if we use the radius 1 standard, then all the houses can be warmed.
Example 2:

Input: houses = [1,2,3,4], heaters = [1,4]
Output: 1
Explanation: The two heater was placed in the position 1 and 4. We need to use radius 1 standard, then all the houses can be warmed.
Example 3:

Input: houses = [1,5], heaters = [2]
Output: 3

Constraints:

1 <= houses.length, heaters.length <= 3 * 104
1 <= houses[i], heaters[i] <= 109

Solution

  • This question is to find the minimum heating radius, then the object divided by two is the radius
  • The interval can only be large and not small. The left interval of the dichotomy is 0. When the house and the heater overlap, the interval of the dichotomy is the largest coordinate
  • Determine whether the specified radius can cover the front and rear houses:
    • Go through each heater
    • Two-point query heater heating radius can cover the leftmost house number
    • If the leftmost radius cannot overlap with the last rightmost, it means that the heating cannot be covered
    • Update the rightmost house number that the current heater radius can cover
    • If the last house can be reached, the coverage is complete
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# O((n+m)logn) time | O(logn) space
class Solution:
def findRadius(self, houses: List[int], heaters: List[int]) -> int:
houses.sort()
heaters.sort()

l, r = 0, max(houses[-1], heaters[-1])
while l <= r:
mid = l + (r-l)//2
if self.canHeat(mid, heaters, houses):
r = mid-1
else:
l = mid+1
return l

def canHeat(self, radius, heaters, houses):
pre_house = 0
for heater in heaters:
cover = bisect.bisect_left(houses, heater-radius)
if cover > pre_house:
return False
pre_house = bisect.bisect_right(houses, heater+radius)
if pre_house >= len(houses):
return True
return False