<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Gauss&#39;s blog</title>
    <link>https://myblog-7fz.pages.dev/</link>
    <description>Recent content on Gauss&#39;s blog</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 14 Jun 2026 19:45:09 +0800</lastBuildDate>
    <atom:link href="https://myblog-7fz.pages.dev/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>3934. 最短唯一子数组</title>
      <link>https://myblog-7fz.pages.dev/posts/3934.-%E6%9C%80%E7%9F%AD%E5%94%AF%E4%B8%80%E5%AD%90%E6%95%B0%E7%BB%84/</link>
      <pubDate>Sun, 14 Jun 2026 19:45:09 +0800</pubDate>
      <guid>https://myblog-7fz.pages.dev/posts/3934.-%E6%9C%80%E7%9F%AD%E5%94%AF%E4%B8%80%E5%AD%90%E6%95%B0%E7%BB%84/</guid>
      <description>&lt;h3 id=&#34;题目分析&#34;&gt;题目分析&lt;/h3&gt;&#xA;&lt;p&gt;如果称一个长度$length$「满足条件」，即表示在$nums$中所有长度为$length$的子数组中存在一个唯一的子数组，那么本题要求的，就是最小的满足条件的长度$length$。&lt;/p&gt;&#xA;&lt;h3 id=&#34;基本思路&#34;&gt;基本思路&lt;/h3&gt;&#xA;&lt;p&gt;分析题目可以发现以下两条性质：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;如果一个给定的长度$length$无法满足条件，即该长度对应的所有子数组中没有单独出现的，那么所有小于等于它的长度都一定不满足条件，说明要找的最小长度一定是大于$length$的；&lt;/li&gt;&#xA;&lt;li&gt;相反，如果一个长度$length$可以满足条件，即存在一个单独出现的长度为$length$的子数组，那么在该长度之下可能还有能够满足条件的长度，结合本题要求&lt;strong&gt;最小&lt;/strong&gt;长度，因此要找的长度一定是小于等于$length$的。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;可以发现，只要确定一个长度是否满足条件，即可确定需要的答案究竟大于还是小于这个长度，因此可以想到采用二分查找的方式寻找答案。&lt;/p&gt;&#xA;&lt;h4 id=&#34;思路1列表模拟计算&#34;&gt;思路1：列表模拟计算&lt;/h4&gt;&#xA;&lt;p&gt;根据上述分析可以发现，二分查找的判断函数应判断给出的中间值$mid$是否是一个满足条件的长度，因此最暴力的方式就是：直接用列表模拟找所有长度为$mid$的子数组，并逐个转为&lt;code&gt;tuple&lt;/code&gt;类型用哈希表计数（转为&lt;code&gt;tuple&lt;/code&gt;是因为&lt;code&gt;list&lt;/code&gt;类型无法直接在哈希表里当作&lt;strong&gt;键&lt;/strong&gt;来计数），其中列表维护长度为$mid$的子数组，即可采用滑动窗口的方式维护。代码很简单直观，如下：&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;check&lt;/span&gt;(mid):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;cur &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;tot &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; defaultdict(int)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(n):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;cur&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(nums[i])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; mid&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;continue&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;tp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; tuple(cur)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;tot[tp] &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;cur&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pop(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; tot&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;values()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;  &lt;/div&gt;&lt;p&gt;不过上面代码中，&lt;code&gt;list&lt;/code&gt;转&lt;code&gt;tuple&lt;/code&gt;以及&lt;code&gt;pop&lt;/code&gt;操作的空间复杂度都很高，最坏情况下单单$tot$中存储值的数量都会逼近$O(n^2)$，因此最终上述代码超内存。&lt;/p&gt;&#xA;&lt;h4 id=&#34;思路2列表哈希化处理&#34;&gt;思路2：列表哈希化处理&lt;/h4&gt;&#xA;&lt;p&gt;既然用列表计数会超内存，那么就需要想将列表压缩的方法。可以发现，如果将列表压缩成一个数字，那么空间复杂度将大大降低，因此这里可以借鉴&lt;strong&gt;哈希化&lt;/strong&gt;的方法。&lt;/p&gt;&#xA;&lt;p&gt;什么叫&lt;strong&gt;哈希化&lt;/strong&gt;？如果要将一个列表哈希化，即意味着用一个特定数字表示该列表。如果要用一个数字$w$代替一个长度为$length$的列表$lst$，则可以使用一个质数$base$，令：&#xA;&lt;/p&gt;&#xA;$$w = lst[0]\times base^{length-1}+lst[1]\times base^{length-2}+...+lst[length-1]\times base^0$$&lt;p&gt;&#xA;即可使用数字$w$表示列表$lst$。&lt;/p&gt;&#xA;&lt;p&gt;因此可以定义$w$，表示当前长度为$length$的子数组对应的数字，如果依旧用上述滑动窗口的方式对其增减元素，假设当前要增加的元素是$nums[i]$，那么要删除的元素就是$nums[i-length]$，即可知道$w$的变化如下：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;$w \rightarrow w\times base$（将每一个元素中$base$的指数都增加1，为新元素腾出位置）&lt;/li&gt;&#xA;&lt;li&gt;$w \rightarrow w-nums[i-length]\times b^{length}$（删除$nums[i-length]$，这里由于上一步将$base$的指数加了1，此处对应的指数就变成了$length$而非原先的$length-1$）&lt;/li&gt;&#xA;&lt;li&gt;$w \rightarrow w+nums[i]$（加上$nums[i]$，此处省略$base^0$）&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;因此根据上述步骤即可实现元素的增减，从而将所有子数组压缩成一个单独的数字。&lt;/p&gt;&#xA;&lt;h3 id=&#34;实现细节&#34;&gt;实现细节&lt;/h3&gt;&#xA;&lt;p&gt;需要注意的是，如果按照上述的计算方式，当$nums$中的值很大并且$length$很大时，$w$的值就会很大，因此可以使用另一个大质数$mod$来对$w$的值不断取模，从而保证不会超出整数范围，同时减少大数相乘的计算量，减少时间。&lt;/p&gt;&#xA;&lt;p&gt;同时，按照思路2进行计算时，可以先计算出第一个窗口对应的值，这样，在后面进行增减运算的循环中不会在同一个循环中实现太多功能，增强可读性。&lt;/p&gt;&#xA;&lt;p&gt;在本题中，如果只用一组$base, mod$数对将每一个子数组进行压缩，不会出现哈希值的冲突，但当数据量增大时，为了防止哈希值的冲突，可以再增加一组$base2,mod2$的值对每一个子数组计算出另一个压缩后的数字，两者同时对应一个子数组，即可降低哈希值冲突的可能性。&#xA;（在下面的代码中，我给出了用两组值分别压缩子数组的方式，如果追求运行速度，可以将有关$b2,m2,pow2,w2$的计算全部删除，可以降低运行时间）&lt;/p&gt;</description>
    </item>
    <item>
      <title>我的第一篇博客</title>
      <link>https://myblog-7fz.pages.dev/posts/my-first-post/</link>
      <pubDate>Sun, 14 Jun 2026 19:44:09 +0800</pubDate>
      <guid>https://myblog-7fz.pages.dev/posts/my-first-post/</guid>
      <description>&lt;h2 id=&#34;简介&#34;&gt;简介&lt;/h2&gt;&#xA;&lt;p&gt;删除.git&lt;/p&gt;&#xA;&lt;p&gt;这是 &lt;strong&gt;粗体&lt;/strong&gt; 文本，这是 &lt;em&gt;斜体&lt;/em&gt; 文本。&lt;/p&gt;&#xA;&lt;p&gt;访问 &lt;a href=&#34;https://gohugo.io&#34;&gt;Hugo&lt;/a&gt; 网站！&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
