# Minimum Number of Taps to Open to Water a Garden in Java

## Problem Statement

The problem states that a gardener wants to water a garden (single-dimensional) by opening the minimum number of taps. The task is to find the minimum number of taps that should be open to water the whole garden, return -1 if the garden cannot be watered.

## Solution to the Problem

For simplicity, it is assumed that the garden is single-dimensional along the axis (either x or y-axis) of the length L, i.e., the garden begins from point 0 and finishes at point L. There are T + 1 tap situated in the garden at the points posArr = [0, 1, 2, …, T]. The range of a tap is defines as (j - rangeArr[j], j + rangeArr[j]) for the j-th tap. The rangeArr[] is an array where the range of a tap is defined. Note that if it is not possible to water the whole garden, then an appropriate message must be displayed on the console.

Let's see an example of it for a better understanding.

### Example:

Input: L = 5, rangeArr = [1, 2, 3, 0, 4, 2]

Output: 1

Explanation: Let's see the range of each tap.

For the first location tap, rangeArr is 1. Thus, the range is [0 - 1, 0 + 1] = [-1, 1].

For the second location tap, rangeArr is 2. Thus, the range is [1 - 2, 1 + 2] = [-1, 3].

For the third location tap, rangeArr is 3. Thus, the range is [2 - 3, 2 + 3] = [-1, 5].

For the fourth location tap, rangeArr is 0. Thus, the range is [3 - 0, 3 + 0] = [3, 3].

For the fifth location tap, rangeArr is 4. Thus, the range is [4 - 4, 4 + 4] = [0, 8].

For the sixth location tap, rangeArr is 2. Thus, the range is [5 - 2, 5 + 2] = [3, 7].

The following diagram shows the same. From the above diagram, it is evident that we can either open a tap located at the 3rd position rangeArr or the tap located at the 5th location rangeArr. It is because these taps can cover the complete length of the garden, which ranges from 0 to 5. Hence, the answer is 1.

## Algorithm

Step 1: The concept to solve the problem is to change the array rangeArr[] into the list of intervals and do sorting them. Sorting should be done according to the starting point of the range of the given taps. Keep the sorting of the intervals in the array intervals[].

Step 2: Pick the element from the array intervals[] (picking should be done from left to right) and check the starting point and endpoint of the range (use loop for picking the elements from the interval). Within the ending point of the range, there has to be a range of another tap, if it is not present, then it is not possible to water the whole garden, and hence, we can stop here to display an appropriate message. If the range is present, then pick that tap whose range is present and increment the count of the tap required.

Step 3: Repeat step two for each tap until we find a tap that can single-handedly cover the whole garden or we have traversed each element of the array intervals[]. Return the count of tap required.

### Implementation

The following is the implementation of the above algorithm.

FileName: FillGardenWithWater.java

Output:

```The minimum number of taps required to water the whole park is: 1
The taps cannot water the whole park.
The minimum number of taps required to water the whole park is: 3
```

Complexity Analysis

In the above program, we have used loops as well as sorting. The loop takes O(n) time, and the sorting takes O(n * log(n)) time. Hence, the total time complexity of the program is O(n + n * log(n)), where n is the total number of taps located. As an array is also used for storing the range, the space complexity of the above program is O(n).

We can optimize the above approach by avoiding sorting. The following approach depicts the same.

## Optimized Approach

Step 1: In this approach, create a jumpArr[] of the size L + 1 that is used to keep track of the maximum range that can be reached from the provided index (current index). In order to do so, assign the value -1 to each of the elements of the array jumpArr[]. -1 for any index means it is not possible to reach that index (coordinate).

Step 2: Take a variable tapCount and initialize it with 1.

Step 3: Traverse the array rangesArr[] and find the range for each tap. The range can be computed as:

start = maximum from (0, i - rangesArr[i])

end = minimum from (L, i + rangesArr[i])

Step 4: Update the array jumpArr[] as jumpArr[start] = maximum from (jumpArr[start], end). If jumpArr = -1, then it means it is not possible to water the whole garden.

Step 5: Take a variable current and assign the value jumpArr to it. Also, take two more variables, nxt, and j. Assign the value 0 to both of them.

While current < L, it means the sgarden is not watered completely till the last index L.

If the nxt is the same as the current, then it means it is not possible to move forward. Thus, it is not possible to water the whole ground.

If nxt is not the same as current, then update current using nxt and update the tapCount by incrementing it with 1.

### Implementation

Let's implement the above approach in a Java program.

FileName: FillGardenWithWater1.java

Output:

```The minimum number of taps required to water the whole park is: 1
The taps cannot water the whole park.
The minimum number of taps required to water the whole park is: 3
```

### Complexity Analysis

In the above program, we have used the nesting of the while loop. However, the elements of the array jumpArr[] are still traversed only once. It is because both the while loops are contributing in the same direction, making the time complexity of the program as O(N). Also, we have used an auxiliary array for keeping track of the maximum range, which makes the space complexity of the program O(N), where N is the total number of taps present in the garden.

## Help Others, Please Share   