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

题目大意:给定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
复制代码

 

posted @   LCAC  阅读(47)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示