There is a one-dimensional garden on the x-axis. The garden starts at the point 0 and ends at the point n. (i.e., the length of the garden is n).
There are n + 1 taps located at points [0, 1, ..., n] in the garden.
Given an integer n and an integer array ranges of length n + 1 where ranges[i] (0-indexed) means the i-th tap can water the area [i - ranges[i], i + ranges[i]] if it was open.
Return the minimum number of taps that should be open to water the whole garden, If the garden cannot be watered return -1.
Input: n =5, ranges =[3,4,1,1,0,0]Output: 1Explanation: The tap at point 0 can cover the interval [-3,3]The tap at point 1 can cover the interval [-3,5]The tap at point 2 can cover the interval [1,3]The tap at point 3 can cover the interval [2,4]The tap at point 4 can cover the interval [4,4]The tap at point 5 can cover the interval [5,5]Opening Only the second tap will water the whole garden [0,5]
This problem is similar to the Jump Game II or interval covering. For each tap, compute the interval it can water. Then, use a greedy approach to always open the tap that extends coverage the farthest among those starting before or at the current end.
classSolution {
public:int minTaps(int n, vector<int>& ranges) {
vector<int> maxReach(n+1, 0);
for (int i =0; i <= n; ++i) {
int l = max(0, i - ranges[i]), r = min(n, i + ranges[i]);
maxReach[l] = max(maxReach[l], r);
}
int ans =0, end =0, far =0;
for (int i =0; i <= n; ++i) {
if (i > far) return-1;
if (i > end) {
ans++;
end = far;
}
far = max(far, maxReach[i]);
}
return ans;
}
};
funcminTaps(nint, ranges []int) int {
maxReach:= make([]int, n+1)
fori:=0; i<=n; i++ {
l, r:= max(0, i-ranges[i]), min(n, i+ranges[i])
ifmaxReach[l] < r {
maxReach[l] = r }
}
ans, end, far:=0, 0, 0fori:=0; i<=n; i++ {
ifi > far { return-1 }
ifi > end {
ans++end = far }
ifmaxReach[i] > far {
far = maxReach[i]
}
}
returnans}
func max(a, bint) int { ifa > b { returna }; returnb }
func min(a, bint) int { ifa < b { returna }; returnb }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution {
publicintminTaps(int n, int[] ranges) {
int[] maxReach =newint[n+1];
for (int i = 0; i <= n; i++) {
int l = Math.max(0, i - ranges[i]), r = Math.min(n, i + ranges[i]);
maxReach[l]= Math.max(maxReach[l], r);
}
int ans = 0, end = 0, far = 0;
for (int i = 0; i <= n; i++) {
if (i > far) return-1;
if (i > end) {
ans++;
end = far;
}
far = Math.max(far, maxReach[i]);
}
return ans;
}
}
classSolution {
funminTaps(n: Int, ranges: IntArray): Int {
val maxReach = IntArray(n+1)
for (i in0..n) {
val l = maxOf(0, i - ranges[i])
val r = minOf(n, i + ranges[i])
maxReach[l] = maxOf(maxReach[l], r)
}
var ans = 0; var end = 0; var far = 0for (i in0..n) {
if (i > far) return -1if (i > end) {
ans++ end = far
}
far = maxOf(far, maxReach[i])
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
defminTaps(n: int, ranges: list[int]) -> int:
maxReach = [0]*(n+1)
for i in range(n+1):
l, r = max(0, i-ranges[i]), min(n, i+ranges[i])
maxReach[l] = max(maxReach[l], r)
ans = end = far =0for i in range(n+1):
if i > far:
return-1if i > end:
ans +=1 end = far
far = max(far, maxReach[i])
return ans
impl Solution {
pubfnmin_taps(n: i32, ranges: Vec<i32>) -> i32 {
let n = n asusize;
letmut max_reach =vec![0; n+1];
for i in0..=n {
let l = i.saturating_sub(ranges[i] asusize);
let r = (i + ranges[i] asusize).min(n);
max_reach[l] = max_reach[l].max(r);
}
let (mut ans, mut end, mut far) = (0, 0, 0);
for i in0..=n {
if i > far { return-1; }
if i > end {
ans +=1;
end = far;
}
far = far.max(max_reach[i]);
}
ans asi32 }
}