LeetCode 题解工作台
包含每个查询的最小区间
给你一个二维整数数组 intervals ,其中 intervals[i] = [left i , right i ] 表示第 i 个区间开始于 left i 、结束于 right i (包含两侧取值, 闭区间 )。区间的 长度 定义为区间中包含的整数数目,更正式地表达是 right i - lef…
5
题型
6
代码语言
3
相关题
当前训练重点
困难 · 二分·搜索·答案·空间
答案摘要
我们注意到,题目中查询的顺序并不会影响答案,并且涉及到的区间也不会发生变化,因此,我们考虑将所有的查询按照从小到大的顺序进行排序,同时将所有的区间按照左端点从小到大的顺序进行排序。 我们使用一个优先队列(小根堆) 来维护当前所有的区间,队列的每个元素是一个二元组 $(v, r)$,表示一个区间长度为 ,右端点为 的区间。初始时,优先队列为空。另外,我们定义一个指针 ,指向当前遍历到的区间,初始…
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 二分·搜索·答案·空间 题型思路
题目描述
给你一个二维整数数组 intervals ,其中 intervals[i] = [lefti, righti] 表示第 i 个区间开始于 lefti 、结束于 righti(包含两侧取值,闭区间)。区间的 长度 定义为区间中包含的整数数目,更正式地表达是 righti - lefti + 1 。
再给你一个整数数组 queries 。第 j 个查询的答案是满足 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 。
提示:
1 <= intervals.length <= 1051 <= queries.length <= 105intervals[i].length == 21 <= lefti <= righti <= 1071 <= queries[j] <= 107
解题思路
方法一:排序 + 离线查询 + 优先队列(小根堆)
我们注意到,题目中查询的顺序并不会影响答案,并且涉及到的区间也不会发生变化,因此,我们考虑将所有的查询按照从小到大的顺序进行排序,同时将所有的区间按照左端点从小到大的顺序进行排序。
我们使用一个优先队列(小根堆) 来维护当前所有的区间,队列的每个元素是一个二元组 ,表示一个区间长度为 ,右端点为 的区间。初始时,优先队列为空。另外,我们定义一个指针 ,指向当前遍历到的区间,初始时 。
我们按照从小到大的顺序依次遍历每个查询 ,并进行如下操作:
- 如果指针 尚未遍历完所有的区间,并且当前遍历到的区间 的左端点小于等于 ,那么我们将该区间加入优先队列中,并将指针 后移一位,循环此过程;
- 如果优先队列不为空,并且堆顶元素的右端点小于 ,那么我们将堆顶元素弹出,循环此过程;
- 此时,如果优先队列不为空,那么堆顶元素就是包含 的最小区间。我们将其长度 加入答案数组 中。
在上述过程结束后,我们返回答案数组 即可。
时间复杂度 ,空间复杂度 。其中 和 分别是数组 和 的长度。
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] * m
pq = []
i = 0
for x, j in queries:
while i < n and intervals[i][0] <= x:
a, b = intervals[i]
heappush(pq, (b - a + 1, b))
i += 1
while pq and pq[0][1] < x:
heappop(pq)
if pq:
ans[j] = pq[0][0]
return ans
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | Depends on the final approach |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Candidate understands how to use sorting to optimize interval processing.
- question_mark
Candidate demonstrates knowledge of binary search in finding the correct interval.
- question_mark
Candidate correctly applies a heap to minimize computational time during interval queries.
常见陷阱
外企场景- error
Not sorting the intervals before applying binary search leads to inefficient solutions.
- error
Failing to use the heap structure efficiently could result in higher-than-expected complexity.
- error
Not handling cases where no interval contains the query could lead to incorrect results.
进阶变体
外企场景- arrow_right_alt
What if the intervals are already sorted?
- arrow_right_alt
How would you handle queries that are out of bounds of all the intervals?
- arrow_right_alt
What if you need to handle a larger range of values, say up to 10^9?