覆盖目标区间的最小区间数
给定一个由N个区间和一个目标区间X组成的数组A[] ,任务是从给定的数组A[]中找到最小的区间数,以使它们完全覆盖目标区间。如果不存在任何此类间隔,则打印“-1” 。
例子:
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.
方法:给定的问题可以通过使用贪心方法来解决。可以观察到,从目标范围内的点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)