1851.包含每个查询的最小区间
链接:1851.包含每个查询的最小区间
难度:Hard
标签:数组、二分查找、排序、扫描线、堆(优先队列)
简介:给你一个二维整数数组 intervals ,其中 intervals[i] = [lefti, righti] 表示第 i 个区间开始于 lefti 、结束于 righti(包含两侧取值,闭区间)。区间的 长度 定义为区间中包含的整数数目,更正式地表达是 righti - lefti + 1 。再给你一个整数数组 queries 。第 j 个查询的答案是满足 lefti <= queries[j] <= righti 的 长度最小区间 i 的长度 。如果不存在这样的区间,那么答案是 -1 。以数组形式返回对应查询的所有答案。
题解 1 - rust
- 编辑时间:2023-07-18
- 执行用时:88ms
- 内存消耗:12.1MB
- 编程语言:rust
- 解法介绍:同上。
#[derive(Clone, PartialEq, Eq, Ord)]
struct Node<'a> {
    idx: usize,
    intervals: &'a Vec<Vec<i32>>,
}
impl<'a> Node<'a> {
    fn new(idx: usize, intervals: &'a Vec<Vec<i32>>) -> Self {
        Node { idx, intervals }
    }
    fn len(&self) -> i32 {
        self.intervals[self.idx][1] - self.intervals[self.idx][0] + 1
    }
}
impl PartialOrd for Node<'_> {
    fn partial_cmp(&self, o: &Self) -> Option<std::cmp::Ordering> {
        o.len().partial_cmp(&self.len())
    }
}
impl Solution {
    pub fn min_interval(mut intervals: Vec<Vec<i32>>, queries: Vec<i32>) -> Vec<i32> {
        let mut res = vec![-1; queries.len()];
        intervals.sort_by_key(|v| v[0]);
        let mut idxs = vec![0; queries.len()]
            .into_iter()
            .enumerate()
            .map(|v| v.0)
            .collect::<Vec<_>>();
        idxs.sort_by_key(|i| queries[*i]);
        let mut q = std::collections::BinaryHeap::<Node>::new();
        let mut iidx = 0;
        for idx in idxs {
            let cur = queries[idx];
            while iidx < intervals.len() && intervals[iidx][0] <= cur {
                q.push(Node::new(iidx, &intervals));
                iidx += 1;
            }
            while !q.is_empty() && intervals[q.peek().unwrap().idx][1] < cur {
                q.pop();
            }
            if !q.is_empty() {
                res[idx] = q.peek().unwrap().len();
            }
        }
        res
    }
}
题解 2 - cpp
- 编辑时间:2023-07-18
- 执行用时:440ms
- 内存消耗:106.5MB
- 编程语言:cpp
- 解法介绍:排序后用堆记录区间最值。
#define SORT(list, fn) sort(list.begin(), list.end(), [&](auto &v1, auto &v2){ fn });
class Solution {
public:
    vector<int> minInterval(vector<vector<int>>& intervals, vector<int>& queries) {
        vector<int> res(queries.size(), -1);
        SORT(intervals, {
            return v1[0] != v2[0] ? v1[0] < v2[0] : v1[1] < v2[1];
        });
        vector<int> idxs;
        for (int i = 0; i < queries.size(); i++) idxs.push_back(i);
        SORT(idxs, {
            return queries[v1] < queries[v2];
        });
        auto cmp = [&](int i1, int i2) {
            int n1 = intervals[i1][1] - intervals[i1][0] + 1,
                n2 = intervals[i2][1] - intervals[i2][0] + 1;
            return n2 < n1;
        };
        priority_queue<int, vector<int>, decltype(cmp)> q(cmp);
        int iidx = 0;
        for (auto &idx : idxs) {
            int cur = queries[idx];
            while (iidx < intervals.size() && intervals[iidx][0] <= cur) {
                q.push(iidx++);
            }
            while (q.size() && intervals[q.top()][1] < cur) {
                q.pop();
            }
            if (q.size()) {
                auto &interval = intervals[q.top()];
                res[idx] = interval[1] - interval[0] + 1;
            }
        }
        return res;
    }
};
题解 3 - python
- 编辑时间:2023-07-18
- 执行用时:944ms
- 内存消耗:64.9MB
- 编程语言:python
- 解法介绍:同上。
class Solution:
    def minInterval(self, intervals: List[List[int]], queries: List[int]) -> List[int]:
        class CmpNode:
            def __init__(self, idx: int) -> None:
                self.idx = idx
            def __lt__(self, o: 'CmpNode') -> bool:
                n1 = intervals[self.idx][1] - intervals[self.idx][0] + 1
                n2 = intervals[o.idx][1] - intervals[o.idx][0] + 1
                return n1 < n2
        res = [-1 for _ in range(len(queries))]
        intervals.sort(key=lambda v: v[0])
        idxs = [i for i in range(len(queries))]
        idxs.sort(key=lambda v: queries[v])
        q: List[CmpNode] = []
        iidx = 0
        for idx in idxs:
            cur = queries[idx]
            while iidx < len(intervals) and intervals[iidx][0] <= cur:
                heappush(q, CmpNode(iidx))
                iidx += 1
            while len(q) and intervals[q[0].idx][1] < cur:
                heappop(q)
            if len(q):
                interval = intervals[q[0].idx]
                res[idx] = interval[1] - interval[0] + 1
        return res