入门力扣自学笔记275 C++ (题目编号:1851)(多看看)

1851. 包含每个查询的最小区间

题目:

给你一个二维整数数组 intervals ,其中 intervals[i] = [lefti, righti] 表示第 i 个区间开始于 lefti 、结束于 righti(包含两侧取值,闭区间)。区间的 长度 定义为区间中包含的整数数目,更正式地表达是 righti - lefti + 1 。

再给你一个整数数组 queries 。第 j 个查询的答案是满足 lefti <= queries[j] <= righti 的 长度最小区间 i 的长度 。如果不存在这样的区间,那么答案是 -1 。

以数组形式返回对应查询的所有答案。


示例 1:

输入:intervals = [[1,4],[2,4],[3,6],[4,4]], queries = [2,3,4,5]
输出:[3,3,1,4]
解释:查询处理如下:
- Query = 2 :区间 [2,4] 是包含 2 的最小区间,答案为 4 - 2 + 1 = 3 。
- Query = 3 :区间 [2,4] 是包含 3 的最小区间,答案为 4 - 2 + 1 = 3 。
- Query = 4 :区间 [4,4] 是包含 4 的最小区间,答案为 4 - 4 + 1 = 1 。
- Query = 5 :区间 [3,6] 是包含 5 的最小区间,答案为 6 - 3 + 1 = 4 。


示例 2:

输入:intervals = [[2,3],[2,5],[1,8],[20,25]], queries = [2,19,5,22]
输出:[2,-1,4,6]
解释:查询处理如下:
- Query = 2 :区间 [2,3] 是包含 2 的最小区间,答案为 3 - 2 + 1 = 2 。
- Query = 19:不存在包含 19 的区间,答案为 -1 。
- Query = 5 :区间 [2,5] 是包含 5 的最小区间,答案为 5 - 2 + 1 = 4 。
- Query = 22:区间 [20,25] 是包含 22 的最小区间,答案为 25 - 20 + 1 = 6 。


提示:

1 <= intervals.length <= 105
1 <= queries.length <= 105
queries[i].length == 2
1 <= lefti <= righti <= 107
1 <= queries[j] <= 107


来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-interval-to-include-each-query
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


思路:

首先给queries排个序。

然后保存区间的左值和区间的右值,进行排序。其次使用优先队列维护所有包含当前询问的区间的长度和对应的id。并且使用map维护优先队列中,但是实际上已经出队列的区间的id。

最后,由于queries是递增的。所以,每次访问到这个询问的时候,左边小于的放入队列,否则就停止放入。因为左边界是有序的,所以后边的都会大于。同理,如果右边界小于了当前的询问,说明之后的询问,都用不到这个区间的。所以直接出队。

入队的时候直接入队。但是出队的时候使用map保存。

每次访问堆顶的时候,直接判断是否在堆中,如果不在继续,直到队列为空,或者没有出队也就是mp[id] = 0的情况。

核心思想就是懒出队。以及有序集合的扫描线。


代码:

class Solution {
public:
    vector minInterval(vector>& intervals, vector& queries) {
        typedef pair a;
        priority_queue,greater> len;
        unordered_map mp;
        int n = intervals.size();
        int m = queries.size();
        vector query(m);
        vector left(n),right(n);
        for(int i = 0;i < n;i++)
        {
            left[i] = {intervals[i][0],i};
            right[i] = {intervals[i][1],i};
        }
        for(int i = 0;i < m;i++)
            query[i] = {queries[i],i};
        sort(left.begin(),left.end());
        sort(right.begin(),right.end());
        sort(query.begin(),query.end());
        vector ans(m);
        for(int i = 0,j = 0,k = 0;i < m;i++)
        {
            auto[q,qid] = query[i];
            while(j < n && left[j].first <= q)
            {
                auto[l,leftid] = left[j++];
                int r = intervals[leftid][1];
                len.push({r - l + 1, leftid});
            }
            while(k < n && right[k].first < q)
            {
                auto[r,rightid] = right[k++];
                mp[rightid] = 1;
            }
            while(!len.empty() && mp[len.top().second])
                len.pop();
            if(len.empty())
                ans[qid] = -1;
            else
                ans[qid] = len.top().first;
        }
        return ans;
    }
};

你可能感兴趣的:(力扣算法学习,c++,leetcode,算法)