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


    LeetCode | 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 。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    示例 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    提示:

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

    思路:扫描线加优先队列,和 LeetCode | 218. 天际线问题 类似。

    把 intervals[i] 的左右两个边界当成是矩形的两条竖边的 x 坐标,矩形的高度为 righti - lefti + 1; queries[j] 就是扫描线,查询的结果就是 queries[j] 所在位置的高度最低的矩形,如果没有矩形,返回 -1。

    例:第一题的图
    img
    当扫描线为 2 时,最低的矩形是 3;扫面线为 4 时,最低的矩形是 1(因为区间为[4, 4], 所以只能看见一根红色的线)。

    实现一:把要查询的区间和扫描线放到同一个数据结构中保存,从左往右遍历

    struct Event {
        int type;
        int pos;
        int para;
        
        Event(int _type, int _pos, int para): type(_type), pos(_pos), para(para) {}
    
        bool operator< (const Event& that) const {
            return pos < that.pos || (pos == that.pos && type < that.type);
        }
    };
    
    vector<int> minInterval(vector<vector<int>>& intervals, vector<int>& queries) {
        int n = intervals.size();
        int m = queries.size();
        
        vector<Event> events;
        for (int i = 0; i < m; ++i) {
            events.emplace_back(1, queries[i], i);
        }
        for (const auto& interval: intervals) {
            events.emplace_back(0, interval[0], interval[1]);
            events.emplace_back(2, interval[1], interval[0]);
        }
    
        sort(events.begin(), events.end());
    
        vector<int> ans(m, -1);
        multiset<int> seg;
        for (const auto& event: events) {
            if (event.type == 0) {
                seg.insert(event.para - event.pos + 1);
            } else if (event.type == 1) {
                if (!seg.empty()) {
                    ans[event.para] = *seg.begin();
                }
            } else {
                int len = event.pos - event.para + 1;
                auto it = seg.find(len);
                seg.erase(it);
            }
        }
        return ans;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    实现二: 用优先队列保存扫描线所在的区间,扫描线不在区间时,区间移出队列。

    vector<int> minInterval(vector<vector<int>>& intervals, vector<int>& queries) {
        vector<int> queries_B = queries, res;
        sort(intervals.begin(), intervals.end());
        sort(queries_B.begin(), queries_B.end());
    
        auto cmp = [](const pair<int, int>& a, const pair<int, int>& b) -> bool { return a.first > b.first; };
        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> que(cmp);
    
        int n = intervals.size(), idx = 0;
        map<int, int> tmp;
        for (int it : queries_B) {
            while (idx < n && intervals[idx][0] <= it) {
                que.emplace(intervals[idx][1] - intervals[idx][0] + 1, intervals[idx][1]);
                idx++;
            }
            while (!que.empty() && que.top().second < it) {
                que.pop();
            }
            tmp[it] = que.empty() ? -1 : que.top().first;
        }
        
        for (int it : queries) {
            res.push_back(tmp[it]);
        }
        return res;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
  • 相关阅读:
    太焦虑了,那些 30多的测试员都是怎么走过来的?
    [附源码]java毕业设计疫情防控期间人员档案追寻系统设计与实现论文
    经典文献阅读之--PL-SLAM(点线SLAM)
    CentOS 管理多版本gcc —— 筑梦之路
    [设计模式]springboot优雅实现策略器模式(加入注册器实现)
    Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password)问题解决
    Vue3:组件高级(下)
    基于 CentOS 7 构建 LVS群集
    常用随机变量的数学期望和方差
    Python爬虫实战案例——第六例
  • 原文地址:https://blog.csdn.net/weixin_42344452/article/details/128080779