Given an array arr[] consisting of N integers, where the ith element represents the range of a sprinkler i.e [i-arr[i], i+arr[i]] it can water, the task is to find the minimum number of the sprinkler to be turned on to water every plant at the gallery. If it is not possible to water every plant, then print -1.
Note: If arr[i] = -1, then the sprinkler cannot be turned on.
Examples:
Input: arr[ ] = {-1, 2, 2, -1, 0, 0}
Output: 2
Explanation:
One of the possible way is:
- Turn on the sprinkler at index 2, it can water the plants in the range [0, 4].
- Turn on the sprinkler at index 5, it can water the plants in the range [5, 5].
Therefore, turning two sprinklers on can water all the plants. Also, it is the minimum possible count of sprinklers to be turned on.
Input: arr[ ] = {2, 3, 4, -1, 2, 0, 0, -1, 0}
Output: -1
Approach: The above problem can be solved using the greedy technique. The idea is to first sort the range by left boundary and then traversing ranges from left and in each iteration select the rightmost boundary a sprinkler can cover having the left boundary in the current range. Follow the steps below to solve the problem:
- Initialize a vector<pair<int, int>> say V to store the range of every sprinkler as a pair.
- Traverse the array arr[] and if arr[i] is not equal to -1 then push the pair (i-arr[i], i+arr[i]) in the vector V.
- Sort the vector of pairs in ascending order by the first element.
- Initialize 2 variables say res, and maxRight to store the minimum sprinklers to be turned on and to store the rightmost boundary of an array.
- Initialize a variable say i as 0 to iterate over the V.
- Iterate until maxRight is less than N and perform the following steps:
- If i is equal to V.size() or V[i].first is greater than maxRight then print -1 and return.
- Store the right boundary of the current sprinkler in the variable say currMax.
- Now iterate until i+1 is less than V.size() and V[i+1].first is less than or equal to maxRight then in each iteration increment i by 1 and update currMax as currMax = max(currMax, V[i].second).
- If currMax is less than the maxRight then print -1 and return.
- Update maxRight as maxRight = currMax+1 then Increment res and i by 1.
- Finally, after completing the above step, print the res as the answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minSprinklers( int arr[], int N)
{
vector<pair< int , int > > V;
for ( int i = 0; i < N; i++) {
if (arr[i] > -1) {
V.push_back(
pair< int , int >(i - arr[i], i + arr[i]));
}
}
sort(V.begin(), V.end());
int maxRight = 0;
int res = 0;
int i = 0;
while (maxRight < N) {
if (i == V.size() || V[i].first > maxRight) {
return -1;
}
int currMax = V[i].second;
while (i + 1 < V.size()
&& V[i + 1].first <= maxRight) {
i++;
currMax = max(currMax, V[i].second);
}
if (currMax < maxRight) {
return -1;
}
res++;
maxRight = currMax + 1;
i++;
}
return res;
}
int main()
{
int arr[] = { -1, 2, 2, -1, 0, 0 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << minSprinklers(arr, N);
}
|
Java
import java.io.*;
import java.util.*;
class pair {
int x;
int y;
pair( int x1, int y1)
{
x = x1;
y = y1;
}
}
class GFG {
static int minSprinklers( int arr[], int N)
{
ArrayList<pair> V = new ArrayList<pair>();
for ( int i = 0 ; i < N; i++) {
if (arr[i] > - 1 ) {
V.add( new pair(i - arr[i], i + arr[i]));
}
}
Collections.sort(V, new Comparator<pair>() {
@Override public int compare(pair p1, pair p2)
{
return p1.x - p2.x;
}
});
int maxRight = 0 ;
int res = 0 ;
int i = 0 ;
while (maxRight < N) {
if (i == V.size() || V.get(i).x > maxRight) {
return - 1 ;
}
int currMax = V.get(i).y;
while (i + 1 < V.size()
&& V.get(i + 1 ).x <= maxRight) {
i++;
currMax = Math.max(currMax, V.get(i).y);
}
if (currMax < maxRight) {
return - 1 ;
}
res++;
maxRight = currMax + 1 ;
i++;
}
return res;
}
public static void main(String[] args)
{
int arr[] = { - 1 , 2 , 2 , - 1 , 0 , 0 };
int N = 6 ;
System.out.println(minSprinklers(arr, N));
}
}
|
Python3
def minSprinklers(arr, N):
V = []
for i in range (N):
if (arr[i] > - 1 ):
V.append([i - arr[i], i + arr[i]])
V.sort()
maxRight = 0
res = 0
i = 0
while (maxRight < N):
if (i = = len (V) or V[i][ 0 ] > maxRight):
return - 1
currMax = V[i][ 1 ]
while (i + 1 < len (V) and V[i + 1 ][ 0 ] < = maxRight):
i + = 1
currMax = max (currMax, V[i][ 1 ])
if (currMax < maxRight):
return - 1
res + = 1
maxRight = currMax + 1
i + = 1
return res
arr = [ - 1 , 2 , 2 , - 1 , 0 , 0 ]
N = len (arr)
print (minSprinklers(arr, N))
|
C#
using System;
using System.Collections.Generic;
class Pair {
public int x;
public int y;
public Pair( int x1, int y1)
{
x = x1;
y = y1;
}
}
class GFG {
static int MinSprinklers( int [] arr, int N)
{
List<Pair> V = new List<Pair>();
for ( int j = 0; j < N; j++) {
if (arr[j] > -1) {
V.Add( new Pair(j - arr[j], j + arr[j]));
}
}
V.Sort((p1, p2) => p1.x.CompareTo(p2.x));
int maxRight = 0;
int res = 0;
int i = 0;
while (maxRight < N) {
if (i == V.Count || V[i].x > maxRight) {
return -1;
}
int currMax = V[i].y;
while (i + 1 < V.Count
&& V[i + 1].x <= maxRight) {
i++;
currMax = Math.Max(currMax, V[i].y);
}
if (currMax < maxRight) {
return -1;
}
res++;
maxRight = currMax + 1;
i++;
}
return res;
}
static void Main( string [] args)
{
int [] arr = { -1, 2, 2, -1, 0, 0 };
int N = 6;
Console.WriteLine(MinSprinklers(arr, N));
}
}
|
Javascript
<script>
function minSprinklers(arr, N) {
let V = [];
for (let i = 0; i < N; i++) {
if (arr[i] > -1) {
V.push([i - arr[i], i + arr[i]]);
}
}
V.sort((a, b) => a - b);
let maxRight = 0;
let res = 0;
let i = 0;
while (maxRight < N) {
if (i == V.length || V[i][0] > maxRight) {
return -1;
}
let currMax = V[i][1];
while (i + 1 < V.length
&& V[i + 1][0] <= maxRight) {
i++;
currMax = Math.max(currMax, V[i][1]);
}
if (currMax < maxRight) {
return -1;
}
res++;
maxRight = currMax + 1;
i++;
}
return res;
}
let arr = [-1, 2, 2, -1, 0, 0];
let N = arr.length;
document.write(minSprinklers(arr, N));
</script>
|
Time Complexity: O(N * log(N))
Auxiliary Space: O(N)