2023-07-18 LeetCode每日一题(包含每个查询的最小区间)

2023-07-18每日一题

一、题目编号

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

二、题目链接

点击跳转到题目位置

三、题目描述

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

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

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

提示:

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

四、解题代码

class Solution {
    int Find(vector<int> &pre, int index){
        while(pre[index] != index){
            index = pre[index];
        }
    return index;
    }

    void Join(vector<int>&pre, int index1, int index2){
        index1 = Find(pre, index1);
        index2 = Find(pre, index2);
        if(index1 != index2){
            pre[index1] = index2;
        }
    }
public:
    vector<int> minInterval(vector<vector<int>>& intervals, vector<int>& queries) {
        int n = queries.size();
        sort(intervals.begin(), intervals.end(),
        [&](vector<int> &a, vector<int> &b){
            if(a[1] - a[0] == b[1] - b[0]){
                return a[0] < b[0];
            }
        return a[1] - a[0] < b[1] - b[0];
        });
        vector<int> res(n, -1);
        
        vector<int> pre(n + 1);
        for(int i = 0; i <= n; ++i){
            pre[i] = i;
        }
        vector<pair<int, int>> query;
        for (int i = 0; i < n; ++i){
            query.emplace_back(queries[i], i);
        }
        sort(query.begin(), query.end());
        for (int i = 0; i < intervals.size(); ++i) {
            int L = intervals[i][0], R = intervals[i][1];
            int l = 0, r = n - 1;
            while (l < r) {
                int mid = l + r >> 1;
                if (query[mid].first >= L) r = mid;
                else l = mid + 1;
            }
            if (query[r].first < L){
                continue;
            }
            for (int x = Find(pre, r); x < n && query[x].first <= R; x = Find(pre, x)) {
                res[query[x].second] = R - L + 1;
                Join(pre, x, x + 1);
            }
            
        }
        return res;
    }
};

五、解题思路

(1) 首先利用排序,第一次排序所需要做的就是按照区间大小从小到大进行排序。

(2) 接着将要搜索的点从小到大进行排序,利用数对可以记录数据。

(3) 利用并查集来进行删点,利用二分来进行加速算法。

你可能感兴趣的:(LeetCode每日一题,leetcode,算法,数据结构)