<?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/%E5%8F%8C%E6%8C%87%E9%92%88/</link>
        <description>Recent content in 双指针 on 奇伏禾</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Sat, 18 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="/tags/%E5%8F%8C%E6%8C%87%E9%92%88/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>LeetCode 热门 100 题之双指针模块精讲（Java 向）</title>
            <link>/p/two-pointers-module/</link>
            <pubDate>Sat, 18 Jul 2026 00:00:00 +0000</pubDate>
            <guid>/p/two-pointers-module/</guid>
            <description>&lt;h2 id=&#34;概述&#34;&gt;概述&#xA;&lt;/h2&gt;&lt;p&gt;双指针（Two Pointers）是数组与链表类问题中最基础也最强大的算法技巧之一。其核心思想是&lt;strong&gt;利用两个指针（通常是索引）以某种策略遍历数据结构&lt;/strong&gt;，从而将原本需要嵌套循环的 O(n²) 甚至 O(n³) 的暴力解法，优化为 O(n) 的单次遍历。&lt;/p&gt;&#xA;&lt;p&gt;双指针主要分为两类场景：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;左右指针（相向指针）&lt;/strong&gt;：两个指针分别从数组的两端向中间移动，常用于处理「有序数组中的配对问题」或「区间最值问题」。典型代表是&lt;strong&gt;盛最多水的容器&lt;/strong&gt;和&lt;strong&gt;三数之和&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;快慢指针（同向指针）&lt;/strong&gt;：两个指针从同一侧出发，移动速度不同，常用于原地去重、移除元素等。典型代表是&lt;strong&gt;移动零&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;双指针最大的优势在于&lt;strong&gt;时间复杂度低（通常 O(n)）且空间复杂度为 O(1)&lt;/strong&gt;，不需要额外的数据结构存储中间结果。本文选取 LeetCode 热门 100 题中双指针模块的 4 道经典题目，从暴力解法的缺陷出发，逐步推导双指针的优化思路，并给出完整的 Java 实现。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;题目一283-移动零&#34;&gt;题目一：283. 移动零&#xA;&lt;/h2&gt;&lt;h3 id=&#34;题目简述&#34;&gt;题目简述&#xA;&lt;/h3&gt;&lt;p&gt;给定一个数组 &lt;code&gt;nums&lt;/code&gt;，编写一个函数将所有 &lt;code&gt;0&lt;/code&gt; 移动到数组的末尾，同时保持非零元素的相对顺序。&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：输入 &lt;code&gt;[0,1,0,3,12]&lt;/code&gt;，输出 &lt;code&gt;[1,3,12,0,0]&lt;/code&gt;&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;要求&lt;/strong&gt;：必须&lt;strong&gt;原地&lt;/strong&gt;修改数组，不能复制额外的数组。&lt;/p&gt;&#xA;&lt;h3 id=&#34;暴力解法&#34;&gt;暴力解法&#xA;&lt;/h3&gt;&lt;p&gt;最直观的思路是新建一个数组，遍历原数组将非零元素按顺序放入新数组，最后在末尾补零。但这样做&lt;strong&gt;空间复杂度为 O(n)&lt;/strong&gt;，不符合「原地修改」的要求。&lt;/p&gt;&#xA;&lt;p&gt;另一种暴力思路是每次遇到零，就将后面的所有元素前移一位，时间复杂度为 O(n²)，效率极低。&lt;/p&gt;&#xA;&lt;h3 id=&#34;优化思路快慢双指针同向指针&#34;&gt;优化思路：快慢双指针（同向指针）&#xA;&lt;/h3&gt;&lt;p&gt;核心思想：使用两个指针，一个&lt;strong&gt;慢指针&lt;/strong&gt;指向下一个非零元素应该放置的位置，一个&lt;strong&gt;快指针&lt;/strong&gt;用于遍历数组。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;快指针 &lt;code&gt;r&lt;/code&gt; 负责扫描整个数组。&lt;/li&gt;&#xA;&lt;li&gt;慢指针 &lt;code&gt;l&lt;/code&gt; 始终指向「已处理区域的下一个位置」，即下一个非零元素应该存放的位置。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;每当快指针遇到非零元素，就将其与慢指针指向的位置交换（或赋值），然后慢指针前进一位。遍历结束后，所有非零元素都在数组前端，剩余位置自然全是零。&lt;/p&gt;&#xA;&lt;h3 id=&#34;具体实现步骤&#34;&gt;具体实现步骤&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;初始化慢指针 &lt;code&gt;l = 0&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;快指针 &lt;code&gt;r&lt;/code&gt; 从 &lt;code&gt;0&lt;/code&gt; 遍历到 &lt;code&gt;n-1&lt;/code&gt;：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;若 &lt;code&gt;nums[r] != 0&lt;/code&gt;，将 &lt;code&gt;nums[r]&lt;/code&gt; 与 &lt;code&gt;nums[l]&lt;/code&gt; 交换，&lt;code&gt;l++&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;遍历结束，数组前 &lt;code&gt;l&lt;/code&gt; 个位置均为非零元素且保持相对顺序，&lt;code&gt;l&lt;/code&gt; 之后均为零。&lt;/li&gt;&#xA;&lt;/ol&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;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Solution&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;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;moveZeroes&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; nums) {&#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; l &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0; &lt;span style=&#34;color:#75715e&#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;int&lt;/span&gt; r &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0; r &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; nums.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt;; r&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; (nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;r&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &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:#75715e&#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; (l &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; r) {&#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; temp &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;l&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;                    nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;l&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;r&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;                    nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;r&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; temp;&#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;                l&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;        }&#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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;复杂度分析&#34;&gt;复杂度分析&#xA;&lt;/h3&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;&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;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;O(1)，仅使用常数额外空间&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;关键点与易错点&#34;&gt;关键点与易错点&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;相对顺序的保持&lt;/strong&gt;：由于慢指针只在遇到非零元素时才前进，且交换操作不改变非零元素之间的相对顺序，因此天然满足题目要求。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;原地修改&lt;/strong&gt;：所有操作都在原数组上进行，没有创建新数组。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;交换 vs 赋值&lt;/strong&gt;：也可以采用「赋值 + 补零」的方式——先将非零元素依次赋值到前面，遍历结束后将剩余位置全部置零。两种方式均可，交换法更简洁。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;题目二11-盛最多水的容器&#34;&gt;题目二：11. 盛最多水的容器&#xA;&lt;/h2&gt;&lt;h3 id=&#34;题目简述-1&#34;&gt;题目简述&#xA;&lt;/h3&gt;&lt;p&gt;给定一个长度为 n 的整数数组 height，有 n 条垂线，第 i 条线的两个端点是 (i, 0) 和 (i, height[i])。找出其中的两条线，使得它们与 x 轴共同构成的容器可以容纳最多的水。&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：输入 height = [1,8,6,2,5,4,8,3,7]，输出 49&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：不能倾斜容器。&lt;/p&gt;&#xA;&lt;h3 id=&#34;暴力解法-1&#34;&gt;暴力解法&#xA;&lt;/h3&gt;&lt;p&gt;遍历所有可能的 (i, j) 组合，计算 &lt;code&gt;min(height[i], height[j]) * (j - i)&lt;/code&gt;，记录最大值。&lt;/p&gt;&#xA;&lt;p&gt;时间复杂度为 O(n²)，当 n 较大时（题目中 n 可达 10⁵）会超时。&lt;/p&gt;&#xA;&lt;h3 id=&#34;优化思路左右双指针相向指针&#34;&gt;优化思路：左右双指针（相向指针）&#xA;&lt;/h3&gt;&lt;p&gt;核心洞察：水的高度由较矮的那条线决定（木桶短板效应）。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;初始化左指针 &lt;code&gt;left = 0&lt;/code&gt;，右指针 &lt;code&gt;right = n - 1&lt;/code&gt;，此时宽度最大。&lt;/li&gt;&#xA;&lt;li&gt;每次计算当前容器容量，更新最大值。&lt;/li&gt;&#xA;&lt;li&gt;关键贪心策略：&lt;strong&gt;永远移动较矮的那一侧指针&lt;/strong&gt;。&#xA;&lt;ul&gt;&#xA;&lt;li&gt;如果移动较高的一侧，宽度减小，高度不可能增加（因为高度由较矮的一侧决定），容量只会更小。&lt;/li&gt;&#xA;&lt;li&gt;移动较矮的一侧，才有机会遇到更高的柱子，从而增大容量。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;具体实现步骤-1&#34;&gt;具体实现步骤&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;初始化 &lt;code&gt;left = 0&lt;/code&gt;，&lt;code&gt;right = height.length - 1&lt;/code&gt;，&lt;code&gt;max = 0&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;当 &lt;code&gt;left &amp;lt; right&lt;/code&gt; 时循环：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;计算当前容量：&lt;code&gt;min(height[left], height[right]) * (right - left)&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;更新 &lt;code&gt;max&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;若 &lt;code&gt;height[left] &amp;lt; height[right]&lt;/code&gt;，则 &lt;code&gt;left++&lt;/code&gt;；否则 &lt;code&gt;right--&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;返回 &lt;code&gt;max&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;/ol&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;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Solution&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;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;maxArea&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; height) {&#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;int&lt;/span&gt; right &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; height.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt; &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;int&lt;/span&gt; max &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;while&lt;/span&gt; (left &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&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;int&lt;/span&gt; h &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Math.&lt;span style=&#34;color:#a6e22e&#34;&gt;min&lt;/span&gt;(height&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;left&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;, height&lt;span style=&#34;color:#f92672&#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;            &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; w &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; right &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;            max &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Math.&lt;span style=&#34;color:#a6e22e&#34;&gt;max&lt;/span&gt;(max, h &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; w);&#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; (height&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;left&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; height&lt;span style=&#34;color:#f92672&#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;                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;            } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&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;        }&#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; max;&#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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;复杂度分析-1&#34;&gt;复杂度分析&#xA;&lt;/h3&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;&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;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;O(1)，仅使用常数额外空间&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;关键点与易错点-1&#34;&gt;关键点与易错点&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;为什么移动短板而非长板&lt;/strong&gt;：这是本题最核心的直觉。容量 = 短板高度 × 宽度。移动长板时，短板高度不变（或变小），宽度减小，容量必减。只有移动短板，短板高度才有可能提升。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;指针相遇即停止&lt;/strong&gt;：当 &lt;code&gt;left &amp;gt;= right&lt;/code&gt; 时，所有可能的容器都已考察完毕。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;与接雨水的区别&lt;/strong&gt;：盛最多水的容器是选两条线求最大容量；接雨水是利用所有柱子计算总积水量。两者虽都用到左右双指针，但逻辑截然不同。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;题目三15-三数之和&#34;&gt;题目三：15. 三数之和&#xA;&lt;/h2&gt;&lt;h3 id=&#34;题目简述-2&#34;&gt;题目简述&#xA;&lt;/h3&gt;&lt;p&gt;给定一个整数数组 nums，判断是否存在三元组 &lt;code&gt;[nums[i], nums[j], nums[k]]&lt;/code&gt; 满足 &lt;code&gt;i != j&lt;/code&gt;、&lt;code&gt;i != k&lt;/code&gt;、&lt;code&gt;j != k&lt;/code&gt;，且 &lt;code&gt;nums[i] + nums[j] + nums[k] == 0&lt;/code&gt;。返回所有和为 0 且不重复的三元组。&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：输入 nums = [-1,0,1,2,-1,-4]，输出 [[-1,-1,2],[-1,0,1]]&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：答案中不可以包含重复的三元组。&lt;/p&gt;&#xA;&lt;h3 id=&#34;暴力解法-2&#34;&gt;暴力解法&#xA;&lt;/h3&gt;&lt;p&gt;三重循环枚举所有三元组，时间复杂度 O(n³)，且去重非常麻烦。&lt;/p&gt;&#xA;&lt;h3 id=&#34;优化思路排序--双指针&#34;&gt;优化思路：排序 + 双指针&#xA;&lt;/h3&gt;&lt;p&gt;核心思想：先排序，再固定一个数，将问题转化为「两数之和」。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;排序后数组有序，可以利用双指针从两端向中间逼近。&lt;/li&gt;&#xA;&lt;li&gt;固定第一个数 &lt;code&gt;nums[i]&lt;/code&gt;，然后在 &lt;code&gt;i+1&lt;/code&gt; 到 &lt;code&gt;n-1&lt;/code&gt; 的范围内用双指针寻找两个数，使得三数之和为 0。&lt;/li&gt;&#xA;&lt;li&gt;排序带来的另一个好处是方便去重：跳过相邻的重复元素。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;具体实现步骤-2&#34;&gt;具体实现步骤&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;对数组进行排序。&lt;/li&gt;&#xA;&lt;li&gt;外层循环 i 从 0 到 n-3：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;剪枝&lt;/strong&gt;：若 &lt;code&gt;nums[i] &amp;gt; 0&lt;/code&gt;，由于数组已排序，后续所有数都 &amp;gt;= nums[i] &amp;gt; 0，三数之和必 &amp;gt; 0，直接 &lt;code&gt;break&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;去重&lt;/strong&gt;：若 &lt;code&gt;i &amp;gt; 0&lt;/code&gt; 且 &lt;code&gt;nums[i] == nums[i-1]&lt;/code&gt;，跳过当前 i，避免重复三元组。&lt;/li&gt;&#xA;&lt;li&gt;初始化左指针 &lt;code&gt;l = i + 1&lt;/code&gt;，右指针 &lt;code&gt;r = n - 1&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;当 &lt;code&gt;l &amp;lt; r&lt;/code&gt; 时循环：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;计算 &lt;code&gt;sum = nums[i] + nums[l] + nums[r]&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;若 &lt;code&gt;sum == 0&lt;/code&gt;：找到一组解，加入结果集；然后移动 l 和 r 并跳过所有重复值。&lt;/li&gt;&#xA;&lt;li&gt;若 &lt;code&gt;sum &amp;lt; 0&lt;/code&gt;：和太小，&lt;code&gt;l++&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;若 &lt;code&gt;sum &amp;gt; 0&lt;/code&gt;：和太大，&lt;code&gt;r--&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;返回结果集。&lt;/li&gt;&#xA;&lt;/ol&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;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Solution&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;public&lt;/span&gt; List&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&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;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;threeSum&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; nums) {&#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;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;&amp;gt;&lt;/span&gt; ans &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; (nums &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; nums.&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; 3) &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; ans;&#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;        Arrays.&lt;span style=&#34;color:#a6e22e&#34;&gt;sort&lt;/span&gt;(nums);&#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; n &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums.&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;&#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; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; n &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; 2; i&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:#75715e&#34;&gt;// 剪枝：最小值已大于0，不可能有解&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; (nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;i&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; 0) &lt;span style=&#34;color:#66d9ef&#34;&gt;break&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:#75715e&#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; (i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; 0 &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;i&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;i &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; 1&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;) &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;&#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; l &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; 1, r &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; n &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;while&lt;/span&gt; (l &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; r) {&#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; sum &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;i&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;l&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;r&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; (sum &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;                    ans.&lt;span style=&#34;color:#a6e22e&#34;&gt;add&lt;/span&gt;(Arrays.&lt;span style=&#34;color:#a6e22e&#34;&gt;asList&lt;/span&gt;(nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;i&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;, nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;l&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;, nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;r&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:#75715e&#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; (l &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; r &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;l&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;l &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; 1&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;) l&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:#75715e&#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; (l &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; r &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;r&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;r &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; 1&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;) r&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;                    l&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;                    r&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;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (sum &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; 0) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    l&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;else&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    r&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;            }&#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; ans;&#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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;复杂度分析-2&#34;&gt;复杂度分析&#xA;&lt;/h3&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;&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;O(n²)：排序 O(n log n)，外层循环 O(n)，内层双指针 O(n)，整体 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;O(log n) 到 O(n)：排序所需栈空间（取决于排序算法），不计输出空间时为 O(1)&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;关键点与易错点-2&#34;&gt;关键点与易错点&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;排序是前提&lt;/strong&gt;：双指针在有序数组上才能根据 sum 与 0 的大小关系决定指针移动方向。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;去重是难点&lt;/strong&gt;：需要在外层循环和找到解后两处进行去重。&#xA;&lt;ul&gt;&#xA;&lt;li&gt;外层：&lt;code&gt;if (i &amp;gt; 0 &amp;amp;&amp;amp; nums[i] == nums[i-1]) continue;&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;内层找到解后：&lt;code&gt;while (l &amp;lt; r &amp;amp;&amp;amp; nums[l] == nums[l+1]) l++;&lt;/code&gt; 和 &lt;code&gt;while (l &amp;lt; r &amp;amp;&amp;amp; nums[r] == nums[r-1]) r--;&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;剪枝优化&lt;/strong&gt;：&lt;code&gt;if (nums[i] &amp;gt; 0) break;&lt;/code&gt; 利用有序数组的特性提前终止。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;指针更新&lt;/strong&gt;：找到解后，在跳过重复值之后，必须执行 &lt;code&gt;l++&lt;/code&gt; 和 &lt;code&gt;r--&lt;/code&gt;，否则会陷入死循环。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;题目四42-接雨水&#34;&gt;题目四：42. 接雨水&#xA;&lt;/h2&gt;&lt;h3 id=&#34;题目简述-3&#34;&gt;题目简述&#xA;&lt;/h3&gt;&lt;p&gt;给定 n 个非负整数表示每个宽度为 1 的柱子的高度图，计算按此排列的柱子，下雨之后能接多少雨水。&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;&lt;strong&gt;示例&lt;/strong&gt;：输入 height = [0,1,0,2,1,0,1,3,2,1,2,1]，输出 6&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;h3 id=&#34;暴力解法-3&#34;&gt;暴力解法&#xA;&lt;/h3&gt;&lt;p&gt;对于每个位置 i，分别向左和向右扫描找到左侧最高柱和右侧最高柱，该位置能接的雨水量为 &lt;code&gt;min(leftMax, rightMax) - height[i]&lt;/code&gt;（若为正）。&lt;/p&gt;&#xA;&lt;p&gt;时间复杂度 O(n²)，空间复杂度 O(1)。&lt;/p&gt;&#xA;&lt;h3 id=&#34;优化思路左右双指针相向指针-1&#34;&gt;优化思路：左右双指针（相向指针）&#xA;&lt;/h3&gt;&lt;p&gt;核心思想：利用两个指针从两端向中间移动，同时维护左侧最高和右侧最高的柱子高度。&lt;/p&gt;&#xA;&lt;p&gt;对于位置 i 能否接水，取决于 &lt;code&gt;min(左侧最高, 右侧最高) - height[i]&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;双指针的精妙之处在于：我们不需要同时知道左右两侧的最高值，只需要知道当前指针所在一侧的最高值是否小于另一侧。&lt;/p&gt;&#xA;&lt;p&gt;若 &lt;code&gt;height[left] &amp;lt; height[right]&lt;/code&gt;，说明 left 位置的「天花板」由左侧最高决定（因为右侧有更高的柱子），此时可以安全地计算 left 位置的积水量。&lt;/p&gt;&#xA;&lt;h3 id=&#34;具体实现步骤-3&#34;&gt;具体实现步骤&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;初始化 &lt;code&gt;left = 0&lt;/code&gt;，&lt;code&gt;right = height.length - 1&lt;/code&gt;，&lt;code&gt;leftMax = 0&lt;/code&gt;，&lt;code&gt;rightMax = 0&lt;/code&gt;，&lt;code&gt;water = 0&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;当 &lt;code&gt;left &amp;lt; right&lt;/code&gt; 时循环：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;若 &lt;code&gt;height[left] &amp;lt; height[right]&lt;/code&gt;：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;若 &lt;code&gt;height[left] &amp;gt;= leftMax&lt;/code&gt;，更新 &lt;code&gt;leftMax = height[left]&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;否则，&lt;code&gt;water += leftMax - height[left]&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;left++&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;否则（&lt;code&gt;height[left] &amp;gt;= height[right]&lt;/code&gt;）：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;若 &lt;code&gt;height[right] &amp;gt;= rightMax&lt;/code&gt;，更新 &lt;code&gt;rightMax = height[right]&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;否则，&lt;code&gt;water += rightMax - height[right]&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;right--&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;返回 &lt;code&gt;water&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;/ol&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;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Solution&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;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;trap&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; height) {&#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;int&lt;/span&gt; right &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; height.&lt;span style=&#34;color:#a6e22e&#34;&gt;length&lt;/span&gt; &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;int&lt;/span&gt; leftMax &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; rightMax &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; water &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; (left &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&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;if&lt;/span&gt; (height&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;left&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; height&lt;span style=&#34;color:#f92672&#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;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (height&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;left&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt; leftMax) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    leftMax &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; height&lt;span style=&#34;color:#f92672&#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;                } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    water &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; leftMax &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; height&lt;span style=&#34;color:#f92672&#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;                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;            } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&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; (height&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;right&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;=&lt;/span&gt; rightMax) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    rightMax &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; height&lt;span style=&#34;color:#f92672&#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;                } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    water &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; rightMax &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; height&lt;span style=&#34;color:#f92672&#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;                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;        }&#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; water;&#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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;复杂度分析-3&#34;&gt;复杂度分析&#xA;&lt;/h3&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;&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;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;O(1)，仅使用常数额外空间&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;关键点与易错点-3&#34;&gt;关键点与易错点&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;为什么 &lt;code&gt;height[left] &amp;lt; height[right]&lt;/code&gt; 时能安全计算左侧&lt;/strong&gt;：因为此时 right 侧存在一个比 left 更高的柱子，所以 left 位置的右侧最高至少是 &lt;code&gt;height[right]&lt;/code&gt;，而左侧最高已知为 &lt;code&gt;leftMax&lt;/code&gt;。因此 left 位置的水位由 &lt;code&gt;leftMax&lt;/code&gt; 决定，可以立即计算。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;与「盛最多水的容器」的区别&lt;/strong&gt;：两者都使用左右双指针从两端向中间移动，但移动条件和计算逻辑完全不同。&#xA;&lt;ul&gt;&#xA;&lt;li&gt;盛最多水：计算面积，移动较矮指针。&lt;/li&gt;&#xA;&lt;li&gt;接雨水：计算积水量，根据两侧最高值决定移动哪一侧。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;初始化边界&lt;/strong&gt;：&lt;code&gt;leftMax&lt;/code&gt; 和 &lt;code&gt;rightMax&lt;/code&gt; 初始为 0，因为边界外没有柱子，高度为 0。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;积水量的计算&lt;/strong&gt;：只有当前高度 &amp;lt; 当前侧最高值时才有积水量，否则更新最高值。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;总结双指针模块对比与通用心法&#34;&gt;总结：双指针模块对比与通用心法&#xA;&lt;/h2&gt;&lt;h3 id=&#34;四题对比一览&#34;&gt;四题对比一览&#xA;&lt;/h3&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;283. 移动零&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;&#x9;&#x9;&lt;td&gt;O(1)&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;11. 盛最多水的容器&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;&#x9;&#x9;&lt;td&gt;O(1)&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;15. 三数之和&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;&#x9;&#x9;&lt;td&gt;O(log n) ~ 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;42. 接雨水&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;&#x9;&#x9;&lt;td&gt;O(1)&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;双指针通用解题心法&#34;&gt;双指针通用解题心法&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;识别题型&lt;/strong&gt;：数组/链表问题，若暴力解法需要多层循环，优先考虑双指针能否优化。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;确定指针类型&lt;/strong&gt;：&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;同向指针（快慢指针）&lt;/strong&gt;：适合原地修改、去重、移除元素等场景。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;相向指针（左右指针）&lt;/strong&gt;：适合有序数组配对、区间最值、面积/水量计算等场景。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;排序是双刃剑&lt;/strong&gt;：三数之和依赖排序才能使用双指针；但盛最多水和接雨水不需要排序，排序反而会破坏原始位置信息。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;明确指针移动条件&lt;/strong&gt;：双指针的核心是每次只移动一个指针，移动哪个取决于具体问题的逻辑。&#xA;&lt;ul&gt;&#xA;&lt;li&gt;移动零：快指针遍历，慢指针记录位置。&lt;/li&gt;&#xA;&lt;li&gt;盛最多水：移动较矮的指针。&lt;/li&gt;&#xA;&lt;li&gt;三数之和：根据 sum 与 0 的大小关系移动。&lt;/li&gt;&#xA;&lt;li&gt;接雨水：根据两侧最高值决定移动哪一侧。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;空间换时间的对立面&lt;/strong&gt;：双指针的核心价值在于 O(1) 空间复杂度，在不使用额外数据结构的前提下将时间复杂度从 O(n²) 降至 O(n)。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;掌握双指针的精髓，关键在于理解**「指针移动的单调性」**——即每次移动指针都能保证不会错过最优解。这四道题覆盖了双指针最典型的应用场景，吃透它们，足以应对绝大多数双指针类面试题。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;</description>
        </item></channel>
</rss>
