Minimum number of intervals to cover the target interval

• Difficulty Level : Hard
• Last Updated : 18 Dec, 2021

Given an array A[] consisting of N intervals and a target interval X, the task is to find the minimum number of intervals from the given array A[] such that they entirely cover the target interval. If there doesn’t exist any such interval then print “-1”.

Examples:

Input: A[] = {{1, 3}, {2, 4}, {2, 10}, {2, 3}, {1, 1}}, X = {1, 10}
Output: 2
Explanation:
From the given 5 intervals, {1, 3} and {3, 10} can be selected. Therefore, the points in the range [1, 3] are covered by the interval {1, 3} and the points in the range [4, 10] are covered by the interval {2, 10}.

Input: A[] = {{2, 6}, {7, 9}, {3, 5}, {6, 10}}, X = {1, 4}
Output: -1
Explanation: There exist no set of intervals in the given array A such that they cover the entire target interval.

Approach: The given problem can be solved by using a Greedy Approach. It can be observed that the most optimal choice of the interval from a point p in the target range is the interval (u, v) such that u <= p and v is the maximum possible. Using this observation, follow the steps below to solve the given problem:

• Sort the given array A[] in increasing order of the starting points of the intervals.
• Create a variable start and initialize it with the starting point of the target interval X. It stores the starting point of the currently selected interval. Similarly, the variable end stores the ending point of the current variable. Initialize it with start – 1.
• Create a variable cnt, which stores the count of the number of selected intervals.
• Iterate through the given array A[] using a variable i.
• If the starting point of the ith interval <= start, update the value of end with the max(end, ending point of the ith interval), else set start = end and increment the value of cnt by 1.
• If the starting point of the ith interval > end or the value of end is already greater than the ending point of the target interval, break the loop.
• Return -1 if the value of end < ending point of target interval, else return the value of cnt.

Below is the implementation of the above approach:

C++

 // C++ program for the above approach   #include using namespace std;   // Function to find the minimum number // of intervals in the array A[] to // cover the entire target interval int minimizeSegment(vector > A,                     pair X) {     // Sort the array A[] in increasing     // order of starting point     sort(A.begin(), A.end());       // Insert a pair of INT_MAX to     // prevent going out of bounds     A.push_back({ INT_MAX, INT_MAX });       // Stores start of current interval     int start = X.first;       // Stores end of current interval     int end = X.first - 1;       // Stores the count of intervals     int cnt = 0;       // Iterate over all the intervals     for (int i = 0; i < A.size();) {           // If starting point of current         // index <= start         if (A[i].first <= start) {             end = max(A[i++].second, end);         }         else {               // Update the value of start             start = end;               // Increment the value             // of count             ++cnt;               // If the target interval is             // already covered or it is             // not possible to move             // then break the loop             if (A[i].first > end                 || end >= X.second) {                 break;             }         }     }       // If the entire target interval     // is not covered     if (end < X.second) {         return -1;     }       // Return Answer     return cnt; }   // Driver Code int main() {     vector > A = {         { 1, 3 }, { 2, 4 }, { 2, 10 }, { 2, 3 }, { 1, 1 }     };     pair X = { 1, 10 };     cout << minimizeSegment(A, X);       return 0; }

Java

 // Java program for the above approach import java.util.ArrayList; import java.util.Comparator;   class GFG {     static class Pair   {     int first;     int second;       public Pair(int f, int s)     {       this.first = f;       this.second = s;     }   }     // Function to find the minimum number   // of intervals in the array A[] to   // cover the entire target interval   public static int minimizeSegment(ArrayList A, Pair X)   {       // Sort the array A[] in increasing     // order of starting point     final Comparator arrayComparator = new Comparator() {       @Override       public int compare(Pair o1, Pair o2) {         return Integer.compare(o1.first, o2.first);       }     };       A.sort(arrayComparator);       // Insert a pair of INT_MAX to     // prevent going out of bounds     A.add(new Pair(Integer.MAX_VALUE, Integer.MIN_VALUE));       // Stores start of current interval     int start = X.first;       // Stores end of current interval     int end = X.first - 1;       // Stores the count of intervals     int cnt = 0;       // Iterate over all the intervals     for (int i = 0; i < A.size();) {         // If starting point of current       // index <= start       if (A.get(i).first <= start) {         end = Math.max(A.get(i++).second, end);       } else {           // Update the value of start         start = end;           // Increment the value         // of count         ++cnt;           // If the target interval is         // already covered or it is         // not possible to move         // then break the loop         if (A.get(i).first > end             || end >= X.second) {           break;         }       }     }       // If the entire target interval     // is not covered     if (end < X.second) {       return -1;     }       // Return Answer     return cnt;   }     // Driver Code   public static void main(String args[]) {     ArrayList A = new ArrayList();     A.add(new Pair(1, 3));     A.add(new Pair(2, 4));     A.add(new Pair(2, 10));     A.add(new Pair(2, 3));     A.add(new Pair(1, 1));     Pair X = new Pair(1, 10);     System.out.println(minimizeSegment(A, X));   } }   // This code is contributed by saurabh_jaiswal.

Python3

 # python program for the above approach   # Function to find the minimum number # of intervals in the array A[] to # cover the entire target interval def minimizeSegment(A, X):       # Sort the array A[] in increasing     # order of starting point       A.sort()       # Insert a pair of INT_MAX to     # prevent going out of bounds       INT_MAX = 2147483647     A.append([INT_MAX, INT_MAX])       # Stores start of current interval     start = X       # Stores end of current interval     end = X - 1       # Stores the count of intervals     cnt = 0       # Iterate over all the intervals     for i in range(0, len(A)):         # If starting point of current         # index <= start           if (A[i] <= start):             end = max(A[i], end)             i = i + 1         else:                           # Update the value of start             start = end               # Increment the value             # of count             cnt = cnt + 1               # If the target interval is             # already covered or it is             # not possible to move             # then break the loop             if (A[i] > end or end >= X):                 break           # If the entire target interval         # is not covered     if (end < X):         return -1           # Return Answer     return cnt     # Driver Code if __name__ == "__main__":     A = [[1, 3], [2, 4], [2, 10], [2, 3], [1, 1]]       X = [1, 10]       print(minimizeSegment(A, X))           # This code is contributed by rakeshsahni

Javascript



Output:

2

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

My Personal Notes arrow_drop_up
Recommended Articles
Page :