🚰Minimum Number of Taps to Open to Water a Garden
Question (LC.1326)
There is a one-dimensional garden on the x-axis. The garden starts at the point
0
and ends at the pointn
. There aren + 1
taps located at points[0, 1, ..., n]
in the garden.Given the garden length
n
and a list of tap rangesranges
whereranges[i]
can cover[i - ranges[i], i + ranges[i]
when that tap is open, find the minimum number of taps open to water the whole garden. If the garden cannot be fully covered, return -1.
Example
I: n = 5, ranges = [3,4,1,1,0,0]
O: 1 because the second tap can cover the entire garden [-3, 5]
I: n = 3, ranges = [0,0,0,0]
O: -1
Approach
This is one class of the interval scheduling problem. The goal is to find the minimum number of intervals to cover a target interval.

Assume an optimal solution
If and can resume from the same previous ending and , and runs longer than , then we can replace with and the rest of solution can remain optimal.
Therefore, by induction, the greedy choice of picking the longest interval with the same acceptable start time proves to be optimal.
Sort by start time because we need to identify gaps between intervals to guarantee correctness.
Code
class Solution:
def convert_rad_to_intv(self, index: int, radius: int) -> Tuple[int, int]:
start = index - radius if index - radius > 0 else 0
return start, index + radius
def minTaps(self, n: int, ranges: List[int]) -> int:
intvs = []
for i in range(len(ranges)):
if ranges[i] != 0:
intvs.append(self.convert_rad_to_intv(i, ranges[i]))
sorted_intvs = sorted(intvs, key=lambda elem: elem[0])
prev_end = -1
current_end = 0
target_end = n
count = 0
for intv in sorted_intvs:
if intv[0] > prev_end:
# discontinuity
if intv[0] > current_end:
return -1
else:
# extend
if intv[1] > current_end:
count += 1
prev_end = current_end
current_end = intv[1]
else:
# swap
if intv[1] > current_end:
current_end = intv[1]
if current_end >= target_end:
return count
return -1
Complexity
Time O(nlogn) + O(n) Space O(n)
Last updated