Open In App

Minimum sprinklers required to be turned on to water the plants

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

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

Recommended Practice

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++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find minimum number of
// sprinkler to be turned on
int minSprinklers(int arr[], int N)
{
    // Stores the leftmost and rightmost
    // point of every sprinklers
    vector<pair<int, int> > V;
    // Traverse the array arr[]
    for (int i = 0; i < N; i++) {
        if (arr[i] > -1) {
            V.push_back(
                pair<int, int>(i - arr[i], i + arr[i]));
        }
    }
    // Sort the array sprinklers in
    // ascending order by first element
    sort(V.begin(), V.end());
 
    // Stores the rightmost range
    // of a sprinkler
    int maxRight = 0;
    // Stores minimum sprinklers
    // to be turned on
    int res = 0;
 
    int i = 0;
 
    // Iterate until maxRight is
    // less than N
    while (maxRight < N) {
 
        // If i is equal to V.size()
        // or V[i].first is greater
        // than maxRight
 
        if (i == V.size() || V[i].first > maxRight) {
            return -1;
        }
        // Stores the rightmost boundary
        // of current sprinkler
        int currMax = V[i].second;
 
        // Iterate until i+1 is less
        // than V.size() and V[i+1].first
        // is less than or equal to maxRight
        while (i + 1 < V.size()
               && V[i + 1].first <= maxRight) {
 
            // Increment i by 1
            i++;
            // Update currMax
            currMax = max(currMax, V[i].second);
        }
 
        // If currMax is less than the maxRight
        if (currMax < maxRight) {
            // Return -1
            return -1;
        }
        // Increment res by 1
        res++;
 
        // Update maxRight
        maxRight = currMax + 1;
 
        // Increment i by 1
        i++;
    }
    // Return res as answer
    return res;
}
 
// Driver code.
int main()
{
    // Input
    int arr[] = { -1, 2, 2, -1, 0, 0 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    cout << minSprinklers(arr, N);
}


Java




// Java program for the above approach
import java.io.*;
import java.util.*;
 
class pair {
    int x;
    int y;
    pair(int x1, int y1)
    {
        x = x1;
        y = y1;
    }
}
 
class GFG {
 
    // Function to find minimum number of
    // sprinkler to be turned on
    static int minSprinklers(int arr[], int N)
    {
 
        // Stores the leftmost and rightmost
        // point of every sprinklers
        ArrayList<pair> V = new ArrayList<pair>();
 
        // Traverse the array arr[]
        for (int i = 0; i < N; i++) {
            if (arr[i] > -1) {
                V.add(new pair(i - arr[i], i + arr[i]));
            }
        }
 
        // Sort the array sprinklers in
        // ascending order by first element
        Collections.sort(V, new Comparator<pair>() {
            @Override public int compare(pair p1, pair p2)
            {
                return p1.x - p2.x;
            }
        });
 
        // Stores the rightmost range
        // of a sprinkler
        int maxRight = 0;
 
        // Stores minimum sprinklers
        // to be turned on
        int res = 0;
 
        int i = 0;
 
        // Iterate until maxRight is
        // less than N
        while (maxRight < N) {
 
            // If i is equal to V.size()
            // or V[i].first is greater
            // than maxRight
 
            if (i == V.size() || V.get(i).x > maxRight) {
                return -1;
            }
            // Stores the rightmost boundary
            // of current sprinkler
            int currMax = V.get(i).y;
 
            // Iterate until i+1 is less
            // than V.size() and V[i+1].first
            // is less than or equal to maxRight
            while (i + 1 < V.size()
                   && V.get(i + 1).x <= maxRight) {
 
                // Increment i by 1
                i++;
 
                // Update currMax
                currMax = Math.max(currMax, V.get(i).y);
            }
 
            // If currMax is less than the maxRight
            if (currMax < maxRight) {
                // Return -1
                return -1;
            }
 
            // Increment res by 1
            res++;
 
            // Update maxRight
            maxRight = currMax + 1;
 
            // Increment i by 1
            i++;
        }
 
        // Return res as answer
        return res;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { -1, 2, 2, -1, 0, 0 };
        int N = 6;
 
        // Function call
        System.out.println(minSprinklers(arr, N));
    }
}
 
// This code is contributed by Manu Pathria


Python3




# Python program for the above approach
 
# Function to find minimum number of
# sprinkler to be turned on
 
 
def minSprinklers(arr, N):
 
    # Stores the leftmost and rightmost
    # point of every sprinklers
    V = []
 
    # Traverse the array arr[]
    for i in range(N):
        if (arr[i] > -1):
            V.append([i - arr[i], i + arr[i]])
 
    # Sort the array sprinklers in
    # ascending order by first element
    V.sort()
 
    # Stores the rightmost range
    # of a sprinkler
    maxRight = 0
 
    # Stores minimum sprinklers
    # to be turned on
    res = 0
 
    i = 0
 
    # Iterate until maxRight is
    # less than N
    while (maxRight < N):
 
        # If i is equal to V.size()
        # or V[i][0] is greater
        # than maxRight
 
        if (i == len(V) or V[i][0] > maxRight):
            return -1
 
        # Stores the rightmost boundary
        # of current sprinkler
        currMax = V[i][1]
 
        # Iterate until i+1 is less
        # than V.size() and V[i+1][0]
        # is less than or equal to maxRight
        while (i + 1 < len(V) and V[i + 1][0] <= maxRight):
 
            # Increment i by 1
            i += 1
            # Update currMax
            currMax = max(currMax, V[i][1])
 
        # If currMax is less than the maxRight
        if (currMax < maxRight):
            # Return -1
            return -1
 
        # Increment res by 1
        res += 1
 
        # Update maxRight
        maxRight = currMax + 1
 
        # Increment i by 1
        i += 1
    # Return res as answer
    return res
 
 
# Driver code.
 
# Input
arr = [-1, 2, 2, -1, 0, 0]
N = len(arr)
 
# Function call
print(minSprinklers(arr, N))
 
# This code is contributed by _saurabh_jaiswal.


C#




using System;
using System.Collections.Generic;
 
// Pair class definition
class Pair {
  public int x;
  public int y;
  public Pair(int x1, int y1)
  {
    x = x1;
    y = y1;
  }
}
 
class GFG {
 
  // Function to find minimum number of
  // sprinkler to be turned on
  static int MinSprinklers(int[] arr, int N)
  {
 
    // Stores the leftmost and rightmost
    // point of every sprinklers
    List<Pair> V = new List<Pair>();
 
    // Traverse the array arr[]
    for (int j = 0; j < N; j++) {
      if (arr[j] > -1) {
        V.Add(new Pair(j - arr[j], j + arr[j]));
      }
    }
 
    // Sort the array sprinklers in
    // ascending order by first element
    V.Sort((p1, p2) => p1.x.CompareTo(p2.x));
 
    // Stores the rightmost range
    // of a sprinkler
    int maxRight = 0;
 
    // Stores minimum sprinklers
    // to be turned on
    int res = 0;
 
    int i = 0;
 
    // Iterate until maxRight is
    // less than N
    while (maxRight < N) {
 
      // If i is equal to V.Count
      // or V[i].first is greater
      // than maxRight
 
      if (i == V.Count || V[i].x > maxRight) {
        return -1;
      }
      // Stores the rightmost boundary
      // of current sprinkler
      int currMax = V[i].y;
 
      // Iterate until i+1 is less
      // than V.Count and V[i+1].first
      // is less than or equal to maxRight
      while (i + 1 < V.Count
             && V[i + 1].x <= maxRight) {
 
        // Increment i by 1
        i++;
 
        // Update currMax
        currMax = Math.Max(currMax, V[i].y);
      }
 
      // If currMax is less than the maxRight
      if (currMax < maxRight) {
        // Return -1
        return -1;
      }
 
      // Increment res by 1
      res++;
 
      // Update maxRight
      maxRight = currMax + 1;
 
      // Increment i by 1
      i++;
    }
 
    // Return res as answer
    return res;
  }
 
  // Driver code
  static void Main(string[] args)
  {
    int[] arr = { -1, 2, 2, -1, 0, 0 };
    int N = 6;
 
    // Function call
    Console.WriteLine(MinSprinklers(arr, N));
  }
}
 
// This code is contributed by phasing17.


Javascript




<script>
 
// JavaScript program for the above approach
 
// Function to find minimum number of
// sprinkler to be turned on
function minSprinklers(arr, N) {
    // Stores the leftmost and rightmost
    // point of every sprinklers
    let V = [];
    // Traverse the array arr[]
    for (let i = 0; i < N; i++) {
        if (arr[i] > -1) {
            V.push([i - arr[i], i + arr[i]]);
        }
    }
    // Sort the array sprinklers in
    // ascending order by first element
    V.sort((a, b) => a - b);
 
    // Stores the rightmost range
    // of a sprinkler
    let maxRight = 0;
    // Stores minimum sprinklers
    // to be turned on
    let res = 0;
 
    let i = 0;
 
    // Iterate until maxRight is
    // less than N
    while (maxRight < N) {
 
        // If i is equal to V.size()
        // or V[i][0] is greater
        // than maxRight
 
        if (i == V.length || V[i][0] > maxRight) {
            return -1;
        }
        // Stores the rightmost boundary
        // of current sprinkler
        let currMax = V[i][1];
 
        // Iterate until i+1 is less
        // than V.size() and V[i+1][0]
        // is less than or equal to maxRight
        while (i + 1 < V.length
            && V[i + 1][0] <= maxRight) {
 
            // Increment i by 1
            i++;
            // Update currMax
            currMax = Math.max(currMax, V[i][1]);
        }
 
        // If currMax is less than the maxRight
        if (currMax < maxRight) {
            // Return -1
            return -1;
        }
        // Increment res by 1
        res++;
 
        // Update maxRight
        maxRight = currMax + 1;
 
        // Increment i by 1
        i++;
    }
    // Return res as answer
    return res;
}
 
// Driver code.
 
// Input
let arr = [-1, 2, 2, -1, 0, 0];
let N = arr.length;
 
// Function call
document.write(minSprinklers(arr, N));
 
 
</script>


Output

2

 Time Complexity: O(N * log(N))
Auxiliary Space: O(N)



Last Updated : 07 Jan, 2024
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads