<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>二分 on 一共十七划</title>
		<link>https://noirzh.com/tags/%E4%BA%8C%E5%88%86/</link>
		<description>Recent content in 二分 on 一共十七划</description>
		<generator>Hugo</generator>
		<language>zh-CN</language>
		
		
		
		
			<lastBuildDate>Mon, 20 Nov 2023 20:23:28 +0800</lastBuildDate>
		
			<atom:link href="https://noirzh.com/tags/%E4%BA%8C%E5%88%86/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>题解-找到 Alice 和 Bob 可以相遇的建筑-单调栈&#43;二分&#43;离线</title>
				<link>https://noirzh.com/%E9%A2%98%E8%A7%A3-%E6%89%BE%E5%88%B0-alice-%E5%92%8C-bob-%E5%8F%AF%E4%BB%A5%E7%9B%B8%E9%81%87%E7%9A%84%E5%BB%BA%E7%AD%91-%E5%8D%95%E8%B0%83%E6%A0%88%E4%BA%8C%E5%88%86%E7%A6%BB%E7%BA%BF/</link>
				<pubDate>Sun, 19 Nov 2023 14:19:00 +0800</pubDate>
				<guid>https://noirzh.com/%E9%A2%98%E8%A7%A3-%E6%89%BE%E5%88%B0-alice-%E5%92%8C-bob-%E5%8F%AF%E4%BB%A5%E7%9B%B8%E9%81%87%E7%9A%84%E5%BB%BA%E7%AD%91-%E5%8D%95%E8%B0%83%E6%A0%88%E4%BA%8C%E5%88%86%E7%A6%BB%E7%BA%BF/</guid>
				<description>&lt;blockquote&gt;&#xD;&#xA;&lt;p&gt;Problem: &lt;a href=&#34;https://leetcode.cn/problems/find-building-where-alice-and-bob-can-meet/description/&#34;&gt;100110. 找到 Alice 和 Bob 可以相遇的建筑&lt;/a&gt;&lt;/p&gt;&#xD;&#xA;&lt;/blockquote&gt;&#xD;&#xA;&lt;h2&gt;思路&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;分解一下题目,发现和Alice和Bob二人顺序没关系,为了方便,我们假设Alice所在建筑位置在左边,称为a,bob就会在右边,称为b&lt;/li&gt;&#xD;&#xA;&lt;li&gt;假设a,b相等,则所在的位置就是b&lt;/li&gt;&#xD;&#xA;&lt;li&gt;若b所在高度大于a,则答案是b&lt;/li&gt;&#xD;&#xA;&lt;li&gt;剩下的就是我们要考虑的一般情况:b的高度小于a,&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;解题方法&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;我们要做的明确,查b的右侧大于a的第一个建筑&lt;/li&gt;&#xD;&#xA;&lt;li&gt;每次都向后查询显然时间复杂度不够,遍历q又是必须的,所以我们想把这个查询压到log级别&lt;/li&gt;&#xD;&#xA;&lt;li&gt;显然可以通过维护右侧单调栈+二分的模式&lt;/li&gt;&#xD;&#xA;&lt;li&gt;但是为每一个点都配单调栈内存不够&lt;/li&gt;&#xD;&#xA;&lt;li&gt;我们发现左边的单调栈一定是右边的转过来的&lt;/li&gt;&#xD;&#xA;&lt;li&gt;所以我们只需要维护一个单调栈&lt;/li&gt;&#xD;&#xA;&lt;li&gt;在遇到对于要处理的点的查询的时候直接查询就行&lt;/li&gt;&#xD;&#xA;&lt;li&gt;也就是我们总体过程是离线查询+单调栈+二分&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;代码细节&lt;/h2&gt;&#xD;&#xA;&lt;ol&gt;&#xD;&#xA;&lt;li&gt;我们先用哈希表记录查询,保证不漏:&lt;/li&gt;&#xD;&#xA;&lt;li&gt;先保证a&amp;lt;=b&lt;/li&gt;&#xD;&#xA;&lt;li&gt;以b为key,存储想查询的值:a和答案位置i&lt;/li&gt;&#xD;&#xA;&lt;li&gt;需要注意的是可能存在多个a的情况,需要用列表而不是一一对应&lt;/li&gt;&#xD;&#xA;&lt;li&gt;从后向前遍历,维护单调栈&lt;/li&gt;&#xD;&#xA;&lt;li&gt;对于遍历的点,如果在哈希表内,说明其是b&lt;/li&gt;&#xD;&#xA;&lt;li&gt;现在维护的单调栈满足需求&lt;/li&gt;&#xD;&#xA;&lt;li&gt;二分查到的答案再写回相应的位置&lt;/li&gt;&#xD;&#xA;&lt;/ol&gt;&#xD;&#xA;&lt;h2&gt;Code&lt;/h2&gt;&#xD;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-python&#34;&gt;class Solution:    &#xD;&#xA;    def leftmostBuildingQueries(self, heights: List[int], queries: List[List[int]]) -&amp;gt; List[int]:&#xD;&#xA;        n=len(queries)  &#xD;&#xA;        hash={}#记录b对应的a和index&#xD;&#xA;        for i in range(n):&#xD;&#xA;            a=min(queries[i])&#xD;&#xA;            b=max(queries[i])&#xD;&#xA;            if b not in hash:&#xD;&#xA;                hash[b]=[]&#xD;&#xA;            hash[b].append([a,i])&#xD;&#xA;&lt;pre&gt;&lt;code&gt;    #记录右边单调递增&#xD;&#xA;    st=[]&#xD;&#xA;    res=[-1]*n&#xD;&#xA;    for i in range(len(heights)-1,-1,-1):&#xD;&#xA;        h=heights[i]&#xD;&#xA;        while st and h&amp;amp;gt;heights[st[-1]]:&#xD;&#xA;            st.pop()&#xD;&#xA;        st.append(i)&#xD;&#xA;        if i in hash:&#xD;&#xA;            b=i&#xD;&#xA;            for a,index in hash[i]:&#xD;&#xA;                if heights[b]&amp;amp;gt;heights[a] or a==b:&#xD;&#xA;                    res[index]=b&#xD;&#xA;                else:&#xD;&#xA;                    l,r=0,len(st)-1&#xD;&#xA;                    while l&amp;amp;lt;=r:&#xD;&#xA;                        mid=(l+r)//2&#xD;&#xA;                        if heights[st[mid]]&amp;amp;gt;heights[a]:&#xD;&#xA;                            l=mid+1&#xD;&#xA;                        else:&#xD;&#xA;                            r=mid-1&#xD;&#xA;                    if (l-1&amp;amp;lt;0):&#xD;&#xA;                        res[index]=-1&#xD;&#xA;                    else:&#xD;&#xA;                        res[index]=st[l-1]&#xD;&#xA;    return res&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
			</item>
	</channel>
</rss>
