首页 > 其他 > 详细

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

时间:2021-05-05 11:57:10      阅读:29      评论:0      收藏:0      [点我收藏+]

题目大意:给定n个区间和m个查询;各个查询的值落在n个区间中最短的区间的长度,没有该区间返回负一

 

该问题很直观的思路是使用离线的方法

1、由于需要求的是最短区间的长度,则使用区间长度作为key进行存储各个区间;从小到达排序n个区间和m个查询

复杂的编码:

技术分享图片
class Solution {
public:
    vector<int> minInterval(vector<vector<int>>& intervals, vector<int>& queries) {
        vector<vector<int>> qq;
        for (int i = 0; i < queries.size(); ++i)
            qq.push_back({queries[i],i});
        
        sort(intervals.begin(), intervals.end());
        sort(qq.begin(), qq.end());
        
        vector<int> rets(queries.size(), -1);
        
        map<int, vector<int>> mv;
        map<int, map<int, vector<int>>::const_iterator> umv;
        int index = 0;
        for (auto& q : qq) {
            while (index < intervals.size() && intervals[index][0] <= q[0]) {
                if (intervals[index][1] < q[0]) {
                    ++index;
                    continue;
                }
                int dif =intervals[index][1] - intervals[index][0] + 1;
                auto iter = mv.find(dif);
                if (iter != mv.end()) {
                    umv.erase(iter->second[1]);
                    iter->second = intervals[index];
                } else {
                    mv[dif] = intervals[index];
                    iter = mv.find(dif);
                }

                auto uiter = umv.find(iter->second[1]);
                if (uiter != umv.end()) {
                    mv.erase(uiter->second);
                }
                umv[iter->second[1]] = iter;
                ++index;
            }
            
            while (! umv.empty() && umv.begin()->first < q[0]) {
                mv.erase(umv.begin()->second);
                umv.erase(umv.begin());
            }
            
            if (mv.empty())
                continue;
            rets[q[1]] = mv.begin()->first;
        }
        return rets;
    }
};
View Code

如上维护两个map来执行插入和删除,编码复杂,并且很容易出错

 

简单的编码:

技术分享图片
class Solution {
public:
    vector<int> minInterval(vector<vector<int>>& intervals, vector<int>& queries) {
        vector<pair<int, int>> qq;
        for (int i = 0; i < queries.size(); ++i)
            qq.push_back({queries[i], i});
        sort(intervals.begin(), intervals.end());
        sort(qq.begin(), qq.end());
        
        vector<int> rets(queries.size(),-1);
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
        int index = 0;
        for (auto& q : qq) {
            while (index < intervals.size() && intervals[index][0] <= q.first) {
                if (intervals[index][1] < q.first) {
                    ++index;
                    continue;
                }
                pq.push({intervals[index][1]-intervals[index][0]+1, intervals[index][1]});
                ++index;
            }
            while (! pq.empty()) {
                auto& p = pq.top();
                if (p.second < q.first)
                    pq.pop();
                else
                    break;
            }
            if (pq.empty())
                continue;
            rets[q.second] = pq.top().first;
        }
        
        return rets;
    }
};
View Code

使用一个堆来维护当前最短区间的长度,程序的单一性让编码变得更简单

 

查询对应的点是否在某个区间,可以反过来思考:该区间有多少个点可以查询的到;因为是最短的区间长度则根据区间的长度从小到大进行区间排序已经找到的查询则写入结果并删除对应的查询

技术分享图片
class Solution {
public:
    vector<int> minInterval(vector<vector<int>>& intervals, vector<int>& queries) {
        sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b)->bool{
            return a[1] - a[0] < b[1] - b[0];
        });
        multimap<int, int> mq;
        for (int i = 0; i < queries.size(); ++i)
            mq.insert({queries[i], i});
        vector<int> rets(queries.size(), -1);
        for (auto& interval : intervals) {
            int start = interval[0];
            int end = interval[1];
            for (auto iter = mq.lower_bound(start); iter != mq.end() && iter->first <= end; iter = mq.erase(iter))
                rets[iter->second] = end - start + 1;
        }
        return rets;
    }
};
View Code

 

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

原文:https://www.cnblogs.com/czwlinux/p/14730633.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!