class Solution {
public:
int minTaps(int n, vector<int>& ranges) {
}
};
1326. 灌溉花园的最少水龙头数目
在 x 轴上有一个一维的花园。花园长度为 n
,从点 0
开始,到点 n
结束。
花园里总共有 n + 1
个水龙头,分别位于 [0, 1, ..., n]
。
给你一个整数 n
和一个长度为 n + 1
的整数数组 ranges
,其中 ranges[i]
(下标从 0 开始)表示:如果打开点 i
处的水龙头,可以灌溉的区域为 [i - ranges[i], i + ranges[i]]
。
请你返回可以灌溉整个花园的 最少水龙头数目 。如果花园始终存在无法灌溉到的地方,请你返回 -1 。
示例 1:
输入:n = 5, ranges = [3,4,1,1,0,0] 输出:1 解释: 点 0 处的水龙头可以灌溉区间 [-3,3] 点 1 处的水龙头可以灌溉区间 [-3,5] 点 2 处的水龙头可以灌溉区间 [1,3] 点 3 处的水龙头可以灌溉区间 [2,4] 点 4 处的水龙头可以灌溉区间 [4,4] 点 5 处的水龙头可以灌溉区间 [5,5] 只需要打开点 1 处的水龙头即可灌溉整个花园 [0,5] 。
示例 2:
输入:n = 3, ranges = [0,0,0,0] 输出:-1 解释:即使打开所有水龙头,你也无法灌溉整个花园。
提示:
1 <= n <= 104
ranges.length == n + 1
0 <= ranges[i] <= 100
原站题解
golang 解法, 执行用时: 8 ms, 内存消耗: 5.3 MB, 提交时间: 2023-02-21 10:58:42
func minTaps(n int, ranges []int) (ans int) { rightMost := make([]int, n+1) for i, r := range ranges { left := max(i-r, 0) rightMost[left] = max(rightMost[left], i+r) } curRight := 0 // 已建造的桥的右端点 nextRight := 0 // 下一座桥的右端点的最大值 for i, r := range rightMost[:n] { // 注意这里没有遍历到 n,因为它已经是终点了 nextRight = max(nextRight, r) if i == curRight { // 到达已建造的桥的右端点 if i == nextRight { // 无论怎么造桥,都无法从 i 到 i+1 return -1 } curRight = nextRight // 造一座桥 ans++ } } return } func max(a, b int) int { if a < b { return b }; return a }
java 解法, 执行用时: 2 ms, 内存消耗: 41.6 MB, 提交时间: 2023-02-21 10:58:28
class Solution { public int minTaps(int n, int[] ranges) { int[] rightMost = new int[n + 1]; for (int i = 0; i <= n; ++i) { int r = ranges[i]; // 这样写可以在 i>r 时少写一个 max // 凭借这个优化,恭喜你超越了 100% 的用户 // 说「超越」是因为原来的最快是 2ms,现在优化后是 1ms if (i > r) rightMost[i - r] = i + r; // 对于 i-r 来说,i+r 必然是它目前的最大值 else rightMost[0] = Math.max(rightMost[0], i + r); } int ans = 0; int curRight = 0; // 已建造的桥的右端点 int nextRight = 0; // 下一座桥的右端点的最大值 for (int i = 0; i < n; ++i) { // 注意这里没有遍历到 n,因为它已经是终点了 nextRight = Math.max(nextRight, rightMost[i]); if (i == curRight) { // 到达已建造的桥的右端点 if (i == nextRight) return -1; // 无论怎么造桥,都无法从 i 到 i+1 curRight = nextRight; // 造一座桥 ++ans; } } return ans; } }
python3 解法, 执行用时: 76 ms, 内存消耗: 15.5 MB, 提交时间: 2023-02-21 10:58:03
class Solution: def minTaps(self, n: int, ranges: List[int]) -> int: right_most = [0] * (n + 1) for i, r in enumerate(ranges): left = max(i - ranges[i], 0) right_most[left] = max(right_most[left], i + ranges[i]) ans = 0 cur_right = 0 # 已建造的桥的右端点 next_right = 0 # 下一座桥的右端点的最大值 for i in range(n): # 注意这里没有遍历到 n,因为它已经是终点了 next_right = max(next_right, right_most[i]) if i == cur_right: # 到达已建造的桥的右端点 if i == next_right: # 无论怎么造桥,都无法从 i 到 i+1 return -1 cur_right = next_right # 造一座桥 ans += 1 return ans