数组(六)-- LC[1851] 包含每个查询的最小区间

news/2025/2/12 21:27:40/

1 包含每个查询的最小区间

1.1 题目描述

给你一个二维整数数组 intervals ,其中 i n t e r v a l s [ i ] = [ l e f t i , r i g h t i ] intervals[i] = [left_i, right_i] intervals[i]=[lefti,righti] 表示第 i i i 个区间开始于 l e f t i left_i lefti 、结束于 r i g h t i right_i righti(包含两侧取值,闭区间)。区间的 长度 定义为区间中包含的整数数目,更正式地表达是 r i g h t i − l e f t i + 1 right_i - left_i + 1 rightilefti+1

再给你一个整数数组 queries 。第 j 个查询的答案是满足 l e f t i < = q u e r i e s [ j ] < = r i g h t i left_i <= queries[j] <= right_i lefti<=queries[j]<=righti 的 长度最小区间 i 的长度 。如果不存在这样的区间,那么答案是 -1 。

以数组形式返回对应查询的所有答案。

示例 1:
输入:intervals = [[1,4],[2,4],[3,6],[4,4]], queries = [2,3,4,5]
输出:[3,3,1,4]
解释:查询处理如下:

  • Query = 2 :区间 [2,4] 是包含 2 的最小区间,答案为 4 - 2 + 1 = 3 。
  • Query = 3 :区间 [2,4] 是包含 3 的最小区间,答案为 4 - 2 + 1 = 3 。
  • Query = 4 :区间 [4,4] 是包含 4 的最小区间,答案为 4 - 4 + 1 = 1 。
  • Query = 5 :区间 [3,6] 是包含 5 的最小区间,答案为 6 - 3 + 1 = 4 。

示例 2
输入:intervals = [[2,3],[2,5],[1,8],[20,25]], queries = [2,19,5,22]
输出:[2,-1,4,6]
解释:查询处理如下:

  • Query = 2 :区间 [2,3] 是包含 2 的最小区间,答案为 3 - 2 + 1 = 2 。
  • Query = 19:不存在包含 19 的区间,答案为 -1 。
  • Query = 5 :区间 [2,5] 是包含 5 的最小区间,答案为 5 - 2 + 1 = 4 。
  • Query = 22:区间 [20,25] 是包含 22 的最小区间,答案为 25 - 20 + 1 = 6 。

解法一:区间端点排序+离线查询+优先队列(小根堆)

首先我们对问题进行分析,对于第 j j j 个查询,可以遍历 intervals \textit{intervals} intervals,找到满足 left i ≤ queries j ≤ right i \textit{left}_i \le \textit{queries}_j \le \textit{right}_i leftiqueriesjrighti 的长度最小区间 i i i 的长度。以上思路对于每个查询,都需要重新遍历 intervals \textit{intervals} intervals

如果查询是递增的,那么我们可以对 intervals \textit{intervals} intervals 按左端点 left \textit{left} left 从小到大进行排序,使用一个指针 i i i 记录下一个要访问的区间 intervals [ i ] \textit{intervals}[i] intervals[i],初始时 i = 0 i = 0 i=0,使用优先队列 pq \textit{pq} pq 保存区间(优先队列的比较 key \textit{key} key 为区间的长度,队首元素为长度最小的区间)。对于第 j j j 个查询,我们执行以下步骤:

  1. 如果 i i i 等于 intervals \textit{intervals} intervals 的长度或 left i > queries [ j ] \textit{left}_i \gt \textit{queries}[j] lefti>queries[j],终止步骤;
  2. intervals [ i ] \textit{intervals}[i] intervals[i] 添加到优先队列 pq \textit{pq} pq,将 i i i 的值加 1,继续执行步骤 1。

此时所有符合 left ≤ queries j ≤ right \textit{left} \le \textit{queries}_j \le \textit{right} leftqueriesjright 的区间都在 pq \textit{pq} pq,我们不断地获取优先队列 pq \textit{pq} pq 的队首区间:

  • 如果队首区间的右端点 right < queries [ j ] \textit{right} \lt \textit{queries}[j] right<queries[j],那么说明该区间不满足条件,从 pq \textit{pq} pq 中出队;

如果队首区间的右端点 right ≥ queries [ j ] \textit{right} \ge \textit{queries}[j] rightqueries[j],那么该区间为第 j j j 个查询的最小区间,终止过程。

对于第 j + 1 j+1 j+1 个查询,因为查询是递增的,所以有 queries [ j + 1 ] ≥ queries [ j ] \textit{queries}[j + 1] \ge \textit{queries}[j] queries[j+1]queries[j],那么此时 pq \textit{pq} pq 中的区间都满足 left ≤ queries [ j + 1 ] \textit{left} \le \textit{queries}[j + 1] leftqueries[j+1]。在第 j j j 个查询中丢弃的区间有 right < queries [ j ] ≤ queries [ j + 1 ] \textit{right} \lt \textit{queries}[j] \le \textit{queries}[j + 1] right<queries[j]queries[j+1],因此丢弃的区间不满足第 j + 1 j + 1 j+1 个查询。同样在第 j + 1 j + 1 j+1 个查询执行与第 j j j 个查询类似的步骤,将可能满足条件的区间加入优先队列 pq \textit{pq} pq 中,那么此时所有满足条件的区间都在优先队列 pq \textit{pq} pq 中,执行类似第 j j j 个查询的出队操作。

由以上分析,如果查询满足递增的条件,那么可以利用优先队列进行优化。题目一次性提供所有的查询,基于离线原理,我们对所有查询从小到大进行排序,然后执行以上算法。

class Solution:def minInterval(self, intervals: List[List[int]], queries: List[int]) -> List[int]:n, m = len(intervals), len(queries)intervals.sort()queries = sorted((x, i) for i, x in enumerate(queries))ans = [-1] * mpq = []i = 0for x, j in queries:while i < n and intervals[i][0] <= x:a, b = intervals[i]heappush(pq, (b - a + 1, b))i += 1while pq and pq[0][1] < x:heappop(pq)if pq:ans[j] = pq[0][0]return ans

复杂度分析

  • 时间复杂度 O ( n × log ⁡ n + m × log ⁡ m ) O(n \times \log n + m \times \log m) O(n×logn+m×logm)
  • 空间复杂度 O ( n + m ) O(n + m) O(n+m)。其中 n 和 m 分别是数组 intervals 和 queries 的长度。

解法二:区间长度排序+离线询问+并查集

class Solution:def minInterval(self, intervals: List[List[int]], queries: List[int]) -> List[int]:m, n = len(intervals), len(queries)intervals.sort(key=lambda x: x[1] - x[0])queries = sorted([(q, i) for i, q in enumerate(queries)])fa = list(range(n + 1))def find(x):if x != fa[x]:fa[x] = find(fa[x])return fa[x]ans = [-1] * nfor l, r in intervals:length = r - l + 1pos = bisect_left(queries, (l, -1))idx = find(pos)while idx < n and queries[idx][0] <= r:ans[queries[idx][1]] = lengthfa[idx] = idx + 1idx = find(idx + 1)return ans

http://www.ppmy.cn/news/1015024.html

相关文章

navigator对象

navigator 对象是 JavaScript 中的一个内置对象&#xff0c;表示当前浏览器的信息和状态。 它提供了访问浏览器相关信息的属性和方法。下面是一些 navigator 对象的常见属性和方法&#xff1a; navigator.userAgent&#xff1a;返回包含浏览器用户代理字符串的字符串。可以使用…

LVS—DR集群的搭建

目录 lvs-dr模式工作原理&#xff1a; 搭建结构&#xff1a; 1、RS&#xff1a; 1&#xff09;两台RS准备好httpd环境和测试文件 2&#xff09;添加虚拟IP&#xff08;vip&#xff09;、添加访问本地vip的静态路由 并抑制ARP 2、DS&#xff1a; 1&#xff09;安装ipvasadm…

【iOS】RunLoop

前言-什么是RunLoop&#xff1f; 什么是RunLoop? 跑圈&#xff1f;字面上理解确实是这样的。 Apple官方文档这样解释RunLoop RunLoop是与线程息息相关的基本结构的一部分。RunLoop是一个调度任务和处理任务的事件循环。RunLoop的目的是为了在有工作的时候让线程忙起来&#…

C#读取加载文件中的内容并修改保存

在编写unity程序时&#xff0c;需要将配置文件中的内容需要读取加载到软件中&#xff0c;因此需要根据文件的相对路径来读取文件中的内容。代码如下&#xff1a; public static string getFileContentByPath(string filePath) {StreamReader streamReader new StreamReader(f…

论文分享--On the Difficulty of Evaluating Baselines A Study on Recommender Systems

与基线比较的数值评估在判断推荐系统中的研究时起着核心作用。在本文中,我们证明了正确运行基线是困难的。我们在两个广泛研究的数据集上证明了这个问题。首先,我们表明,在过去五年中,在许多出版物中使用的基线对Movielens 10M基准的结果是次优的。通过仔细设置一个普通矩阵…

机械厂工厂360全景展示拍摄制作,以便随时随地进行展示和更新

随着5G互联网技术的不断发展&#xff0c;线上全景虚拟展示已经成为了一种重要的展示方式。在工业领域中&#xff0c;厂区线上全景虚拟展示的应用也越来越广泛。 厂区线上vr全景虚拟展示是VR全景制作公司公司借助VR全景和web3d开发技术把企业的环境、研发、生产、产品、质检、仓…

使用Spring Initializr方式构建Spring Boot项目

除了可以使用Maven方式构建Spring Boot项目外&#xff0c;还可以通过Spring Initializr方式快速构建Spring Boot项目。从本质上说&#xff0c;Spring lnitializr是一个Web应用&#xff0c;它提供了一个基本的项目结构&#xff0c;能够帮助我们快速构建一个基础的Spring Boot项目…

匈牙利算法详解

匈牙利算法(Hungarian Algorithm)是一种组合优化算法(combinatorial optimization algorithm)&#xff0c;用于求解指派问题(assignment problem)&#xff0c;算法时间复杂度为O(N^3)。Harold Kuhn发表于1955年&#xff0c;由于该算法基于两位匈牙利数学家的早期研究成果&#…