📜  覆盖目标区间的最小区间数

📅  最后修改于: 2022-05-13 01:56:10.648000             🧑  作者: Mango

覆盖目标区间的最小区间数

给定一个由N个区间和一个目标区间X组成的数组A[] ,任务是从给定的数组A[]中找到最小的区间数,以使它们完全覆盖目标区间。如果不存在任何此类间隔,则打印“-1”

例子:

方法:给定的问题可以通过使用贪心方法来解决。可以观察到,从目标范围内的点p开始的区间的最佳选择是区间(u, v) ,使得u <= p并且v是可能的最大值。使用此观察结果,请按照以下步骤解决给定问题:

  • 按区间起点的升序对给定数组A[]进行排序。
  • 创建一个变量start并将其初始化为目标区间X的起点。它存储当前选定间隔的起点。同样,变量end存储当前变量的结束点。用start - 1初始化它。
  • 创建一个变量cnt ,它存储所选间隔数的计数。
  • 使用变量i遍历给定的数组A[]
  • 如果第 i区间的起点 <= start,则用 max(end, 第 i区间的终点) 更新 end 的值,否则设置start = end并将cnt的值增加1
  • 如果第 i区间的起点 > end 或者end的值已经大于目标区间的终点,则中断循环。
  • 如果 end < 目标区间的结束点返回-1 ,否则返回cnt的值。

下面是上述方法的实现:

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[0]
 
    # Stores end of current interval
    end = X[0] - 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][0] <= start):
            end = max(A[i][1], 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][0] > end or end >= X[1]):
                break
 
        # If the entire target interval
        # is not covered
    if (end < X[1]):
        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


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG
{
 
  public class Pair
  {
    public int first;
    public 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(List A, Pair X) {
 
    // Sort the array []A in increasing
    // order of starting point
 
    A.Sort((a,b)=>a.first-b.first);
 
    // Insert a pair of INT_MAX to
    // prevent going out of bounds
    A.Add(new Pair(int.MaxValue, int.MinValue));
 
    // 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.Count;) {
 
      // If starting point of current
      // index <= start
      if (A[i].first <= start) {
        end = Math.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
  public static void Main(String []args) {
    List A = new List();
    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);
    Console.WriteLine(minimizeSegment(A, X));
  }
}
 
// This code is contributed by Rajput-Ji


Javascript


输出:
2

时间复杂度: O(N*log N)
辅助空间: O(1)