<?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>/tags/%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/</link>
        <description>Recent content in 滑动窗口 on 奇伏禾</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Sun, 19 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="/tags/%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>滑动窗口模块 — LeetCode 热门 100 题精讲（Java 向）</title>
            <link>/p/sliding-window-module/</link>
            <pubDate>Sun, 19 Jul 2026 00:00:00 +0000</pubDate>
            <guid>/p/sliding-window-module/</guid>
            <description>&lt;h2 id=&#34;滑动窗口思想概述&#34;&gt;滑动窗口思想概述&#xA;&lt;/h2&gt;&lt;p&gt;滑动窗口是双指针的一种特殊形态，专治 &lt;strong&gt;子串（子数组）相关的最优/判定问题&lt;/strong&gt;。它维护一个左右指针（&lt;code&gt;left&lt;/code&gt; 和 &lt;code&gt;right&lt;/code&gt;）定义的窗口区间，通过不断移动右指针扩大窗口、移动左指针缩小窗口，在单次线性扫描中探索所有可能的可行解，从而避免暴力枚举所有子串的 O(n²) 开销。&lt;/p&gt;&#xA;&lt;p&gt;滑动窗口的核心在于 &lt;strong&gt;窗口内数据状态的动态维护&lt;/strong&gt;，通常借助哈希表或数组计数器记录窗口内元素的频次、种类、和等指标。当窗口满足某个条件时，尝试收缩左边界以寻找更优解，否则扩张右边界以包含更多元素。&lt;/p&gt;&#xA;&lt;p&gt;LeetCode 热门 100 题中，有三道题是滑动窗口的经典代表：&lt;strong&gt;3. 无重复字符的最长子串&lt;/strong&gt;（求最长满足条件的子串）、&lt;strong&gt;438. 找到字符串中所有字母异位词&lt;/strong&gt;（求所有满足条件的子串起始位置）、&lt;strong&gt;76. 最小覆盖子串&lt;/strong&gt;（求最短满足条件的子串）。它们覆盖了滑动窗口的三种主要题型：最长、所有、最短，掌握这三题即可应对绝大多数场景。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;1-无重复字符的最长子串leetcode-3&#34;&gt;1. 无重复字符的最长子串（LeetCode 3）&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;题目&lt;/strong&gt;：给定一个字符串 &lt;code&gt;s&lt;/code&gt;，找出其中不含有重复字符的 &lt;strong&gt;最长子串&lt;/strong&gt; 的长度。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;暴力法&lt;/strong&gt;：枚举所有子串，用哈希集合检查是否有重复字符，时间复杂度 O(n²)。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;滑动窗口思路&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;用右指针 &lt;code&gt;right&lt;/code&gt; 遍历字符串，将字符逐个加入窗口。&lt;/li&gt;&#xA;&lt;li&gt;用哈希集合（或数组计数）记录窗口内出现过的字符。&lt;/li&gt;&#xA;&lt;li&gt;当遇到重复字符时，左指针 &lt;code&gt;left&lt;/code&gt; 不断右移，并从集合中移除移出字符，直到窗口中不再有重复字符。&lt;/li&gt;&#xA;&lt;li&gt;每次调整后，用当前窗口长度 &lt;code&gt;right - left + 1&lt;/code&gt; 更新最大值。&lt;/li&gt;&#xA;&lt;/ul&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-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;lengthOfLongestSubstring&lt;/span&gt;(String s) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Set&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;Character&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; set &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; HashSet&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; left &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0, maxLen &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; right &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0; right &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; s.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;(); right&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;        &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; c &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; s.&lt;span style=&#34;color:#a6e22e&#34;&gt;charAt&lt;/span&gt;(right);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; (set.&lt;span style=&#34;color:#a6e22e&#34;&gt;contains&lt;/span&gt;(c)) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            set.&lt;span style=&#34;color:#a6e22e&#34;&gt;remove&lt;/span&gt;(s.&lt;span style=&#34;color:#a6e22e&#34;&gt;charAt&lt;/span&gt;(left));&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            left&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;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        set.&lt;span style=&#34;color:#a6e22e&#34;&gt;add&lt;/span&gt;(c);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        maxLen &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Math.&lt;span style=&#34;color:#a6e22e&#34;&gt;max&lt;/span&gt;(maxLen, right &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; left &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; 1);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; maxLen;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;复杂度&lt;/strong&gt;：O(n)，每个字符最多被加入和移出各一次，空间 O(min(m, n))（m 为字符集大小）。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：while 循环处理重复，确保窗口内始终无重复字符；更新最大长度的时机在调整完成后。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;2-找到字符串中所有字母异位词leetcode-438&#34;&gt;2. 找到字符串中所有字母异位词（LeetCode 438）&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;题目&lt;/strong&gt;：给定字符串 s 和 p，找到 s 中所有 p 的异位词的起始索引。异位词指字母种类和数量相同，顺序不限。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;暴力法&lt;/strong&gt;：枚举 s 中所有长度为 len(p) 的子串，统计字母频次比较，O(n * m)。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;滑动窗口思路&lt;/strong&gt;：窗口固定为 p.length() 大小，用右指针 right 移动，同时维护一个计数器数组记录窗口内各字母频次。当窗口长度正好等于 p.length() 时，比较窗口频次数组与 p 的频次数组是否相等，若相等则记录左指针。每次右移后，将新字符加入频次，并移除左指针指向的旧字符（保持窗口长度固定）。&lt;/p&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-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; List&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;Integer&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;findAnagrams&lt;/span&gt;(String s, String p) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    List&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;Integer&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; res &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; ArrayList&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (s.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; p.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;()) &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; res;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt; pCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;26&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;    &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt; winCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;26&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;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; c : p.&lt;span style=&#34;color:#a6e22e&#34;&gt;toCharArray&lt;/span&gt;()) pCount&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;c &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&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;    &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; left &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; right &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0; right &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; s.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;(); right&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;        winCount&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;s.&lt;span style=&#34;color:#a6e22e&#34;&gt;charAt&lt;/span&gt;(right) &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&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;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (right &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; left &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; 1 &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; p.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;()) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            winCount&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;s.&lt;span style=&#34;color:#a6e22e&#34;&gt;charAt&lt;/span&gt;(left) &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&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;            left&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;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (right &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; left &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; 1 &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; p.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; Arrays.&lt;span style=&#34;color:#a6e22e&#34;&gt;equals&lt;/span&gt;(winCount, pCount)) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            res.&lt;span style=&#34;color:#a6e22e&#34;&gt;add&lt;/span&gt;(left);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; res;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;复杂度&lt;/strong&gt;：O(n * 26) = O(n)，空间 O(1)（固定 26 长度）。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：窗口长度固定，每次移动右指针后，若长度超出则移动左指针，保证窗口长度恰好为 m；比较频次数组可直接用 &lt;code&gt;Arrays.equals&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;3-最小覆盖子串leetcode-76&#34;&gt;3. 最小覆盖子串（LeetCode 76）&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;题目&lt;/strong&gt;：给定字符串 s 和 t，在 s 中找到包含 t 中所有字符（包括重复字符）的 &lt;strong&gt;最短子串&lt;/strong&gt;，若不存在返回空串。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;难点&lt;/strong&gt;：窗口需要动态伸缩，既要包含所有所需字符，又要尽量短。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;滑动窗口思路&lt;/strong&gt;：用哈希表 need 记录 t 中每个字符的需求数量，用 window 记录当前窗口内各字符出现次数。用 formed 记录当前窗口中满足需求（频次 &amp;gt;= need）的字符种类数，当 formed == need.size() 时，窗口已覆盖所有所需字符。此时尝试收缩左指针以缩小窗口，并不断更新最小长度和起始位置；收缩时若某个字符频次不满足需求，则 formed 减少。继续移动右指针扩大窗口。&lt;/p&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-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; String &lt;span style=&#34;color:#a6e22e&#34;&gt;minWindow&lt;/span&gt;(String s, String t) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Map&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;Character, Integer&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; need &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; HashMap&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Map&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;Character, Integer&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; window &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; HashMap&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; c : t.&lt;span style=&#34;color:#a6e22e&#34;&gt;toCharArray&lt;/span&gt;()) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        need.&lt;span style=&#34;color:#a6e22e&#34;&gt;put&lt;/span&gt;(c, need.&lt;span style=&#34;color:#a6e22e&#34;&gt;getOrDefault&lt;/span&gt;(c, 0) &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; 1);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; left &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0, right &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; formed &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0, required &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; need.&lt;span style=&#34;color:#a6e22e&#34;&gt;size&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; minLen &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Integer.&lt;span style=&#34;color:#a6e22e&#34;&gt;MAX_VALUE&lt;/span&gt;, start &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; (right &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; s.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;()) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; c &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; s.&lt;span style=&#34;color:#a6e22e&#34;&gt;charAt&lt;/span&gt;(right);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        window.&lt;span style=&#34;color:#a6e22e&#34;&gt;put&lt;/span&gt;(c, window.&lt;span style=&#34;color:#a6e22e&#34;&gt;getOrDefault&lt;/span&gt;(c, 0) &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; 1);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (need.&lt;span style=&#34;color:#a6e22e&#34;&gt;containsKey&lt;/span&gt;(c) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; window.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(c).&lt;span style=&#34;color:#a6e22e&#34;&gt;intValue&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; need.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(c).&lt;span style=&#34;color:#a6e22e&#34;&gt;intValue&lt;/span&gt;()) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            formed&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;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; (left &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; right &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; formed &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; required) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            c &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; s.&lt;span style=&#34;color:#a6e22e&#34;&gt;charAt&lt;/span&gt;(left);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (right &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; left &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; 1 &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; minLen) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                minLen &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; right &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; left &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; 1;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                start &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; left;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            window.&lt;span style=&#34;color:#a6e22e&#34;&gt;put&lt;/span&gt;(c, window.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(c) &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; 1);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (need.&lt;span style=&#34;color:#a6e22e&#34;&gt;containsKey&lt;/span&gt;(c) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; window.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(c).&lt;span style=&#34;color:#a6e22e&#34;&gt;intValue&lt;/span&gt;() &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; need.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(c).&lt;span style=&#34;color:#a6e22e&#34;&gt;intValue&lt;/span&gt;()) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                formed&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;            }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            left&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;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        right&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;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; minLen &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; Integer.&lt;span style=&#34;color:#a6e22e&#34;&gt;MAX_VALUE&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; : s.&lt;span style=&#34;color:#a6e22e&#34;&gt;substring&lt;/span&gt;(start, start &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; minLen);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;复杂度&lt;/strong&gt;：O(n + m)，空间 O(k)（k 为字符集大小）。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：formed 记录的是字符种类数（去重），只有当某个字符的窗口频次 &lt;strong&gt;恰好等于&lt;/strong&gt; 需求频次时才增加，减少时机类似；收缩时先更新最小长度，再移出左字符，最后调整 formed。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;三题对比与启发&#34;&gt;三题对比与启发&#xA;&lt;/h2&gt;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;题目&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;窗口大小&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;目标&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;收缩条件&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;记录时机&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;时间复杂度&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;无重复字符最长&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;动态（尽量大）&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;求最大长度&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;窗口内出现重复&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;每次调整后&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;O(n)&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;字母异位词&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;固定 (len p)&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;求所有起始位置&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;窗口大小 &amp;gt; len p&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;窗口大小 == len p 且频次匹配&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;O(n)&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;最小覆盖子串&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;动态（尽量小）&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;求最小长度&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;窗口满足覆盖&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;满足覆盖时&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;O(n)&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;&lt;strong&gt;共同本质&lt;/strong&gt;：滑动窗口利用双指针同步移动，在右指针扩张、左指针收缩的过程中，只关注当前窗口的有效信息，通过状态变量（如计数、formed）避免每次重新统计窗口，将 O(n²) 的暴力枚举降为 O(n)。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;不同侧重&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;无重复字符：以&amp;quot;无重复&amp;quot;为约束，遇到冲突即收缩。&lt;/li&gt;&#xA;&lt;li&gt;字母异位词：固定窗口长度，滑动比较频次。&lt;/li&gt;&#xA;&lt;li&gt;最小覆盖子串：以&amp;quot;包含所有所需字符&amp;quot;为约束，满足后不断收缩找最短。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;总结滑动窗口模块的核心心法&#34;&gt;总结：滑动窗口模块的核心心法&#xA;&lt;/h2&gt;&lt;p&gt;滑动窗口的精髓在于用两个指针维护一个动态区间，并利用计数器或哈希表 O(1) 维护区间状态。所有题目都遵循&amp;quot;右指针扩大窗口找可行解，左指针缩小窗口优化解&amp;quot;的通用框架。&lt;/p&gt;&#xA;&lt;p&gt;应用滑动窗口的通用模板：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;定义窗口状态变量（计数器、频次数组、满足条件计数等）。&lt;/li&gt;&#xA;&lt;li&gt;右指针 right 逐位移动，更新状态。&lt;/li&gt;&#xA;&lt;li&gt;当窗口满足题目条件时（或触发收缩条件时），进入 while 循环，移动左指针 left 缩小窗口，同时更新答案（长度、起始位置等）。&lt;/li&gt;&#xA;&lt;li&gt;在收缩过程中，同步更新窗口状态，直到条件不再满足。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;掌握这三题，就能识别大多数滑动窗口变种（如固定窗口、可变窗口、求最值、求所有解）。面试中遇到子串相关题目，优先思考能否用滑动窗口 O(n) 解决。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;</description>
        </item></channel>
</rss>
