Blage's Coding Blage's Coding
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
  • 数组

    • 搜索

    • 二分查找

    • 排序

    • 边界判断

    • 双指针法

    • 连续子数组

    • 差分数组

    • 模拟

    • 区间问题

      • 56.合并区间
      • 763. 划分字母区间
      • 452. 用最少数量的箭引爆气球
      • 1851. 包含每个查询的最小区间
        • 1.优先队列+区间排序
      • 2276. 统计区间中的整数数目
  • 链表

  • 字符串

  • 二叉树

  • 动态规划

  • 深搜回溯

  • 数学贪心

  • 堆栈队列

  • 前缀和

  • 算法设计

  • 位运算

  • WA

  • 算法
  • 数组
  • 区间问题
phan
2023-07-18
目录

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

# 1851. 包含每个查询的最小区间 (opens new window)

# 1.优先队列+区间排序

预处理阶段先进行三个排序:

  • intervals按照左边界从小到大进行排序
  • queries按照从小到大进行排序。返回最终结果集需要按照原先查询顺序,因此开辟二维数组保存原先下标。
  • 创建一个优先级队列,排序规则按照区间大小进行排序。

对于每一个查询要想找到最小区间,要满足三步①左边界小于当前值②右边界大于当前值③区间最小。操作如下:

  1. 首先将所有左边界小于等于当前查询值的区间加入队列。相当于找到所有满足①条件的区间。这里区间已经排过序,因此直接按照index顺序入队。
  2. 将队列中所有右边界小于当前查询值的区间移出。相当于过滤掉不满足②条件的区间。这里查询值排过序,因此出队区间肯定小于后续查询值,所以移除后不会影响后续查询值。
  3. 区间放在优先级队列进行操作,因此天然满足条件③。队首元素区间大小即为当前查询结果。

在上面三个排序性的约束下,入队的元素都有可能成为当前和后续查询的结果,而出队的元素一定不可能成为当前和后续查询的结果。故整个查询过程时间复杂度O(intervals.length)。

总结:【1】区间问题除了区间大小以外,还可以考虑按照左右边界排序的思路解题。

【2】在线查询复杂度比较高,可使用“离线查询”。本质上就是改变批量数据的查询顺序,将结果原序返回。

  • 在线查询:每次获得一个请求,查询一次并直接放回结果。
  • 离线查询:通过改变和处理原本查询的顺序,批量/顺序处理完所有数据之后,再将结果按照绑定的原先查询顺序返回。
class Solution {
    public int[] minInterval(int[][] intervals, int[] queries) {
        int[] res=new int[queries.length];
        int[][] que=new int[queries.length][2];
        for(int i=0;i<queries.length;i++){
            que[i][0]=queries[i];
            que[i][1]=i;
        }
        //对intervals排序
        Arrays.sort(intervals,new Comparator<int[]>(){
            public int compare(int[] o1,int[] o2){
                return o1[0]-o2[0];
            }
        });
        //对que进行排序
        Arrays.sort(que,new Comparator<int[]>(){
            public int compare(int[] o1,int[] o2){
                return o1[0]-o2[0];
            }
        });
        //优先级队列
        PriorityQueue<int[]> queue=new PriorityQueue<>(new Comparator<int[]>(){
            public int compare(int[] o1,int[] o2){
                return o1[1]-o1[0]-(o2[1]-o2[0]);
            }
        });
        int inx=0;
        for(int i=0;i<que.length;i++){
            //入队:所有区间【a,b】的左边界a只要小于等于当前查询que【i】,则入栈
            while(inx<intervals.length&&intervals[inx][0]<=que[i][0]){
                queue.offer(intervals[inx]);
                inx++;
            }
            //出队:所有区间【a,b】的右边界b只要小于当前查询que【i】,则入栈
            while(queue.size()>0&&queue.peek()[1]<que[i][0]){
                queue.poll();
            }
            if(queue.size()>0) res[que[i][1]]=queue.peek()[1]-queue.peek()[0]+1;
            else res[que[i][1]]=-1;
        }
        return res;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
编辑 (opens new window)
#Leetcode
上次更新: 2023/12/15, 15:49:57
452. 用最少数量的箭引爆气球
2276. 统计区间中的整数数目

← 452. 用最少数量的箭引爆气球 2276. 统计区间中的整数数目→

Theme by Vdoing | Copyright © 2023-2024 blageCoder
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式