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
相关推荐
jiao_mrswang34 分钟前
leetcode-18-四数之和
算法·leetcode·职场和发展
qystca42 分钟前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法
薯条不要番茄酱42 分钟前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
今天吃饺子1 小时前
2024年SCI一区最新改进优化算法——四参数自适应生长优化器,MATLAB代码免费获取...
开发语言·算法·matlab
是阿建吖!1 小时前
【优选算法】二分查找
c++·算法
王燕龙(大卫)1 小时前
leetcode 数组中第k个最大元素
算法·leetcode
不去幼儿园2 小时前
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
人工智能·python·算法·机器学习·强化学习
Mr_Xuhhh2 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
盼海3 小时前
排序算法(五)--归并排序
数据结构·算法·排序算法
网易独家音乐人Mike Zhou6 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot