包含每个查询的最小区间
给你一个二维整数数组 intervals ,其中 intervals[i] = [lefti, righti] 表示第 i 个区间开始于 lefti 、结束于 righti(包含两侧取值,闭区间)。
区间的长度定义为区间中包含的整数数目,更正式地表达是 righti - lefti + 1 。
再给你一个整数数组 queries 。第 j 个查询的答案是满足 lefti <= queries[j] <= righti 的 长度最小区间 i 的长度 。
如果不存在这样的区间,那么答案是 -1 。以数组形式返回对应查询的所有答案
1. 离线查询 + 优先队列
由于要找最小区间长度,必然要采取某种贪心策略
对于查询点,找左边界小于查询点,同时右边界大于查询点的区间
这里使用优先队列方便查找最小的区间
同时对不满足条件的区间移出队列
class Solution {
public:
vector<int> minInterval(vector<vector<int>>& intervals, vector<int>& queries) {
vector<int> qindex(queries.size()); //从小到大记录查询点下标
iota(qindex.begin(), qindex.end(), 0);
sort(qindex.begin(), qindex.end(), [&](int i, int j){
return queries[i] < queries[j];
});
sort(intervals.begin(), intervals.end(), [](const vector<int> &it1, const vector<int> &it2){//区间按左边界进行排序
return it1[0] < it2[0];
});
priority_queue<vector<int>> pq;//优先队列
vector<int> res(queries.size(), -1);//不满足条件为-1
int i = 0; //区间点下标
for (auto qi : qindex) { //从左到右遍历查询点
while (i < intervals.size() && intervals[i][0] <= queries[qi]) {//处理左边界小于查询点的区间
int l = intervals[i][1] - intervals[i][0] + 1;//计算当前区间长度
pq.push({-l, intervals[i][0], intervals[i][1]});//将候选区间入队、按长度升序排
i++;
}
while (!pq.empty() && pq.top()[2] < queries[qi]) {//右边界小于查询点,之后没用,移出队列
pq.pop();
}
if (!pq.empty()) {//第一个必然是满足条件的最小区间
res[qi] = -pq.top()[0];
}
}
return res;
}
};