给定一个数组Intervals[]由N对整数组成,其中每对表示值范围[L, R] 。此外,给定一个由M 个查询组成的整数数组Q[] 。对于每个查询,任务是找到包含该元素的最小范围的大小。如果不存在有效间隔,则返回-1 。
例子
Input: Intervals[] = [[1, 4], [2, 3], [3, 6], [9, 25], [7, 15], [4, 4]]
Q[] = [7, 50, 2]
Output: [9, -1, 2]
Explanation: Element 7 is in the range [7, 15] only therefore, the answer will be 15 – 7 + 1 = 8. Element 50 is in no range. Therefore, the answer will be -1.
Similarly, element 2 is in the range [2, 3] and [1, 4] but the smallest range is [2, 3] therefore, the answer will be 3-2+1 = 2.
Input: Intervals[] = [[1, 4], [2, 4], [3, 6]]
Q[] = [2, 3]
Output: [3, 3]
朴素方法:解决问题的最简单方法是遍历数组range[]并为每个查询找到包含给定元素的最小范围。
时间复杂度: O(N×M)
辅助空间: O(M)
高效的方法:可以通过使用 priority_queue 进一步优化上述方法。请按照以下步骤解决问题:
- 初始化一个向量向量,比如Queries并将所有查询连同它的索引一起插入到数组Q 中。
- 使用向量的默认排序函数对向量区间和查询进行排序。
- 初始化一个priority_queue,比如说pq ,key 为Interval 的大小,value 为范围的右边界。
- 初始化一个向量,假设结果将存储每个查询的最小范围的大小。
- 初始化一个整数变量,比如i ,它将跟踪数组Intervals的遍历元素。
- 在范围内迭代 [0, M-1]使用变量j并执行以下步骤:
- 在i < Intervals.size()和Intervals[i][0] <= Queries[j][0] 时迭代,插入-(Intervals[i][1] – Intervals[i][0] + 1),Intervals [i][1]作为对并将i的值增加1 。
- 现在从 priority_queue pq 中删除所有元素,其中正确的元素小于Qeries[j][0] 。
- 如果priority_queue pq>0的大小,则将result[Queries[j][1]]的值修改为pq.top()[0] 。
- 返回数组res[]作为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the size of minimum
// Interval that contains the given element
vector minInterval(vector >& intervals,
vector& q)
{
// Store all the queries
// along with their index
vector > queries;
for (int i = 0; i < q.size(); i++)
queries.push_back({ q[i], i });
// Sort the vector intervals and queries
sort(intervals.begin(), intervals.end());
sort(queries.begin(), queries.end());
// Max priority queue to keep track
// of intervals size and right value
priority_queue > pq;
// Stores the result of all the queries
vector result(queries.size(), -1);
// Current position of intervals
int i = 0;
for (int j = 0; j < queries.size(); j++) {
// Stores the current query
int temp = queries[j][0];
// Insert all the intervals whose left value
// is less than or equal to the current query
while (i < intervals.size()
&& intervals[i][0] <= temp) {
// Insert the negative of range size and
// the right bound of the interval
pq.push(
{ -intervals[i][1] + intervals[i][0] - 1,
intervals[i++][1] });
}
// Pop all the intervals with right value
// less than the current query
while (!pq.empty() && temp > pq.top()[1]) {
pq.pop();
}
// Check if the valid interval exists
// Update the answer for current query
// in result array
if (!pq.empty())
result[queries[j][1]] = -pq.top()[0];
}
// Return the result array
return result;
}
// Driver Code
int main()
{
// Given Input
vector > intervals
= { { 1, 4 }, { 2, 3 }, { 3, 6 }, { 9, 25 }, { 7, 15 }, { 4, 4 } };
vector Q = { 7, 50, 2, 3, 4, 9 };
// Function Call
vector result = minInterval(intervals, Q);
// Print the result for each query
for (int i = 0; i < result.size(); i++)
cout << result[i] << " ";
return 0;
}
9 -1 2 2 1 9
时间复杂度: O(NlogN+MlogM)
辅助空间:O(N+M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。