[LeetCode] 1326. Minimum Number of Taps to Open to Water a Garden

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.

Example 1:

Input: n = 5, ranges = [3,4,1,1,0,0]
Output: 1
Explanation: 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]

Example 2:

Input: n = 3, ranges = [0,0,0,0]
Output: -1
Explanation: Even if you activate all the four taps you cannot water the whole garden.

Constraints:

  • 1 <= n <= 104
  • ranges.length == n + 1
  • 0 <= ranges[i] <= 100

灌溉花园的最少水龙头数目。

在 x 轴上有一个一维的花园。花园长度为 n,从点 0 开始,到点 n 结束。

花园里总共有 n + 1 个水龙头,分别位于 [0, 1, ..., n] 。

给你一个整数 n 和一个长度为 n + 1 的整数数组 ranges ,其中 ranges[i] (下标从 0 开始)表示:如果打开点 i 处的水龙头,可以灌溉的区域为 [i -  ranges[i], i + ranges[i]] 。

请你返回可以灌溉整个花园的 最少水龙头数目 。如果花园始终存在无法灌溉到的地方,请你返回 -1 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-number-of-taps-to-open-to-water-a-garden
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这道题有多种解法,这里我提供一个扫描线的思路。

这道题给了若干个水龙头,问最少需要多少个水龙头才能确保所有范围都能被浇水,所以这里我对 input 数据做了一点处理。ranges 数组表示的是每个水龙头的覆盖范围,我把 ranges 变为一个二维数组,表示每个水龙头能覆盖的左边界和右边界,记为 region。接着我对 region 排序,排序的规则是左边界更小的在前,如果左边界一样,那么右边界小的在前。

排序之后我们需要几个变量,res 记录最后需要几个水龙头,right 记录当前水龙头能覆盖到的右边界的下标,cur 记录的是当前遍历到第几个水龙头了。其余部分参见代码注释。

时间O(nlogn)

空间O(n)

Java实现

 1 class Solution {
 2     public int minTaps(int n, int[] ranges) {
 3         // 二维数组记录每个水龙头能覆盖的范围
 4         int[][] region = new int[n + 1][2];
 5         for (int i = 0; i <= n; i++) {
 6             int[] temp = new int[2];
 7             temp[0] = Math.max(0, i - ranges[i]);
 8             temp[1] = Math.min(n, i + ranges[i]);
 9             region[i] = temp;
10         }
11         Arrays.sort(region, (a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
12 
13         int res = 0;
14         int right = 0;
15         int cur = 0;
16         while (cur < n + 1) {
17             // 当前区间无法覆盖到最右的有效工作范围,那么就会存在覆盖不到的间隙
18             if (region[cur][0] > right) {
19                 break;
20             }
21             int rt = right;
22             while (cur < n + 1 && region[cur][0] <= right) {
23                 rt = Math.max(rt, region[cur][1]);
24                 cur++;
25             }
26             res++;
27             right = rt;
28             if (right == n) {
29                 break;
30             }
31         }
32         return right == n ? res : -1;
33     }
34 }

 

LeetCode 题目总结

posted @ 2023-02-21 07:34  CNoodle  阅读(38)  评论(0编辑  收藏  举报