搜索
您的当前位置:首页正文

离线处理查询,LeetCode 2940. 找到 Alice 和 Bob 可以相遇的建筑

来源:步旅网

一、题目

1、题目描述

2、接口描述

python3
 ​
class Solution:
    def leftmostBuildingQueries(self, heights: List[int], queries: List[List[int]]) -> List[int]:

3、原题链接


二、解题报告

1、思路分析

比较直观的思路是:线段树二分 或者 ST表预处理+二分

但是这种直接借助数据结构的方式不利于思维的训练,这种题目往往可以使用离线处理 + 数据结构维护,往难了出可以主席树,整体二分,莫队……比较常见的就是先离线处理查询,再按照某种遍历顺序处理巧妙化解问题

本题考虑两种做法:最小堆 / 单调栈+二分

F1 最小堆

查询(a, b)(a <= b),如果 height[a] < height[b] 或者a == b,那么答案就是b

对于一般情况:

将查询放到右端点b处,记保存每个下标作为右端点的查询,即 找到b右边大于height[a] 的最靠近b的索引

然后我们顺序遍历heights,最小堆保存遍历过的下标的所有以其为右端点的查询

如果堆顶 查询 值小于当前遍历到的height,那么弹出堆顶,维护答案

F2 单调栈+二分

和上一个方法预处理查询方法相同

我们考虑每个查询要找到右边第一个大于指定值的索引

我们可以倒序遍历heights,维护一个单调栈,栈顶到栈底递增,那么遍历过程中,如果有询问,栈顶到栈底第一个大于的就是答案

2、复杂度

时间复杂度: O(n + qlogq)空间复杂度:O(n)

3、代码详解

F1 最小堆
class Solution:
    def leftmostBuildingQueries(self, heights: List[int], queries: List[List[int]]) -> List[int]:
        n = len(heights)
        q = [[] for _ in range(n)]
        ans = [-1] * len(queries)
        for i, (a, b) in enumerate(queries):
            if a > b:
                a, b = b, a
            if a == b or heights[b] > heights[a]:
                ans[i] = b
            else:
                q[b].append((heights[a], i))

        pq = []
        for i, x in enumerate(heights):
            while pq and pq[0][0] < x:
                ans[heappop(pq)[1]] = i
            for Q in q[i]:
                heappush(pq, Q)
        return ans
F2 单调栈二分
class Solution:
    def leftmostBuildingQueries(self, heights: List[int], queries: List[List[int]]) -> List[int]:
        n = len(heights)
        q = [[] for _ in range(n)]
        ans = [-1] * len(queries)
        for i, (a, b) in enumerate(queries):
            if a > b:
                a, b = b, a
            if a == b or heights[b] > heights[a]:
                ans[i] = b
            else:
                q[b].append((heights[a], i))
        st = []
        for i in range(len(heights) - 1, -1, -1):
            for h, qi in q[i]:
                j = bisect_left(st, -h, key=lambda i:-heights[i])
                if j:
                    ans[qi] = st[j - 1]
            while st and heights[i] >= heights[st[-1]]:
                st.pop()
            st.append(i)
        return ans

因篇幅问题不能全部显示,请点此查看更多更全内容

Top