2023-07-18力扣每日一题-有点难

链接:

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

题意:

给定一个区间二维数组,有N个[L,R]区间(闭区间)

给定一组查询,有M个正整数,求存在于区间数组中的最小 R-L+1满足L<=M[i]<=R

解:

本来看标签有个扫描线,想写个差分,然后排序查询整O(1)查询的,没写出来QWQ,也不知道有没有这种整法

优先队列倒是会写

因为每个查询独立且一次性给出,所以可以离线查询,对查询数组从小到大排序(记得保留原序),称为NM

对于一个左端点L小于NM[i]的区间,对于NM[i]以及其后面的查询都是可能合法的区间,因为NM递增

对于一个右端点R小于NM[i]的区间,对于NM[i]以及其后面的查询都是一定非法的区间,因为NM递增

所以当查询从小到大时,L若从小到大,则对于这个查询合法则对后面的所以查询皆合法,R若从小到大,则对这个查询非法则对后面的所以查询皆非法

那么步骤就是,排序区间数组和查询数组,双指针遍历,对于每个查询:

将所有NM[i]>=L,加入一个容器,即步骤1,得到一个所有可能合法区间

将容器内所有NM[i]>R,剔除,即步骤2,可以得到一个该值的所有一定合法区间

最后选择容器中最小R-L+1,得到该查询的答案。难点就在于在这个容器中删除NM[i]>R

这时候就要使用我们的优先队列 了,使小的R-L+1在前面,在这基础上,小的R在前面(由于L都是合法的所以不需要存L)

这时候只要不断删除顶部非法的R,就可以得到最小的R-L+1,然后我这边用map存了答案,遍历一遍原序,访问map拿答案

OA:为什么不是先排序R再排序R-L+1

​ 因为假设[1,7] [2,7] [6,8] ,对于查询7来说选择[4,8] 是最好的,找最小的R-L+1才是优先,不过同样的,如果是查询8,按照我们先R-L+1再R的顺序排序[6,8] [2,7] [1,7] [6,8]直接就是最好的,会有非法的R残留,不过重点是找最小的合法的R-L+1,优先提供最小的R-L+1,,再去判断它合不合法

实际代码:

c++ 复制代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
/*
bool cmp1(const PII& L,const PII& R)//自定义排序函数 
{
    if(L.first==R.first) return L.second>R.second; 
    else return L.first>R.first; 
}*/
struct cmp1//自定义排序类 
{
    bool operator() (const PII& L,const PII& R)
    {
        if(L.first==R.first) return L.second>R.second; 
        else return L.first>R.first; 
    }
};
vector<int> minInterval(vector<vector<int>>& intervals, vector<int>& queries)
{
    vector<int> q=queries;//拷贝-原序 
    //priority_queue<PII,vector<PII>,decltype(&cmp1)>p_q(cmp1); //函数式自定义优先队列 
    priority_queue<PII,vector<PII>,cmp1>p_q;//类式自定义优先队列 
    //优先队列 小距离优先 小右端点优先 
    map<int,int>mtp;//非原序存储答案 
    
    sort(queries.begin(),queries.end());
    sort(intervals.begin(),intervals.end());
    
    int left=0,lg=intervals.size();
    for(auto querie:queries)
    {
        while(left<lg && intervals[left][0]<=querie)//左端点符合 - 步骤1
        {
            p_q.push({intervals[left][1]-intervals[left][0]+1,intervals[left][1]});
            left++;
        }
        while(!p_q.empty() && p_q.top().second<querie)//右端点不符合 - 步骤2
        {
            p_q.pop(); 
        }
        if(!p_q.empty()) mtp[querie]=p_q.top().first;
    }
    
    for(auto &iq:q)
    {
        if(mtp[iq]==0) mtp[iq]=-1;
        iq=mtp[iq];
    }
    
    return q;
}
int main()
{
    int n;cin>>n;
    vector<vector<int>> intervals;
    vector<int> queries;
    for(int i=1;i<=n;i++)
    {
        int a,b;cin>>a>>b;
        vector<int>temp{a,b};
        intervals.push_back(temp);
    }
    while(cin>>n)
    {
        queries.push_back(n);
    }
    vector<int>ans=minInterval(intervals,queries);
    for(auto i:ans)
    {
        cout<<i<<" ";
    }
    cout<<endl;
    return 0;
}

限制:

  • 1 <= intervals.length <= 105
  • 1 <= queries.length <= 105
  • intervals[i].length == 2
  • 1 <= lefti <= righti <= 107
  • 1 <= queries[j] <= 107
相关推荐
幸运超级加倍~13 分钟前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
yannan2019031320 分钟前
【算法】(Python)动态规划
python·算法·动态规划
埃菲尔铁塔_CV算法22 分钟前
人工智能图像算法:开启视觉新时代的钥匙
人工智能·算法
EasyCVR23 分钟前
EHOME视频平台EasyCVR视频融合平台使用OBS进行RTMP推流,WebRTC播放出现抖动、卡顿如何解决?
人工智能·算法·ffmpeg·音视频·webrtc·监控视频接入
linsa_pursuer24 分钟前
快乐数算法
算法·leetcode·职场和发展
小芒果_0125 分钟前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
qq_4340859027 分钟前
Day 52 || 739. 每日温度 、 496.下一个更大元素 I 、503.下一个更大元素II
算法
Beau_Will27 分钟前
ZISUOJ 2024算法基础公选课练习一(2)
算法
XuanRanDev29 分钟前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
gkdpjj31 分钟前
C++优选算法十 哈希表
c++·算法·散列表