<?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%8A%80%E5%B7%A7/</link>
        <description>Recent content in 技巧 on 奇伏禾</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Wed, 22 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="/tags/%E6%8A%80%E5%B7%A7/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>技巧模块 — LeetCode 热门 100 题精讲（Java 向）</title>
            <link>/p/technique-module/</link>
            <pubDate>Wed, 22 Jul 2026 00:00:00 +0000</pubDate>
            <guid>/p/technique-module/</guid>
            <description>&lt;h2 id=&#34;技巧模块概述&#34;&gt;技巧模块概述&#xA;&lt;/h2&gt;&lt;p&gt;算法题中有一类题目，不依赖传统的 DP、二分或贪心框架，而是需要巧妙的 &lt;strong&gt;数学性质&lt;/strong&gt; 或 &lt;strong&gt;指针操作&lt;/strong&gt; 来达到最优解。这类题目考验的是对数据结构和特定规律的洞察力，一旦掌握技巧，代码往往非常简洁且高效。&lt;/p&gt;&#xA;&lt;p&gt;本章精选的五道题分别代表了五种不同的算法技巧：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;136. 只出现一次的数字&lt;/strong&gt;：异或运算的交换律与结合律。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;169. 多数元素&lt;/strong&gt;：Boyer-Moore 投票算法（正负抵消）。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;75. 颜色分类&lt;/strong&gt;：荷兰国旗问题（三指针原地分区）。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;31. 下一个排列&lt;/strong&gt;：字典序排列的生成规律（双指针反转）。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;287. 寻找重复数&lt;/strong&gt;：链表判环（Floyd 判圈算法）在数组上的应用。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;1-只出现一次的数字leetcode-136&#34;&gt;1. 只出现一次的数字（LeetCode 136）&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;题目&lt;/strong&gt;：给定一个非空整数数组，其中某个元素只出现一次，其余每个元素均出现两次。找出那个只出现一次的元素。要求 O(n) 时间，O(1) 空间。&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;交换律：a ^ b ^ c = a ^ c ^ b&lt;/li&gt;&#xA;&lt;li&gt;任何数与 0 异或等于本身：0 ^ a = a&lt;/li&gt;&#xA;&lt;li&gt;任何数与自己异或等于 0：a ^ a = 0&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;将所有数字进行异或运算，成对出现的数字会抵消为 0，最终剩下的就是只出现一次的数字。&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; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;singleNumber&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; res &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; num : nums) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        res &lt;span style=&#34;color:#f92672&#34;&gt;^=&lt;/span&gt; num;&#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)，空间 O(1)。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：异或运算是处理&amp;quot;成对出现&amp;quot;问题的杀手锏，不仅限于数字，也可扩展到字符（如找出现奇数次的字符）。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;2-多数元素leetcode-169&#34;&gt;2. 多数元素（LeetCode 169）&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;题目&lt;/strong&gt;：给定大小为 n 的数组，找出其中出现次数大于 ⌊n/2⌋ 的元素。要求 O(n) 时间，O(1) 空间。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;常规思路&lt;/strong&gt;：排序后取中位数（O(n log n)），或哈希统计（O(n) 空间）。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;技巧解法（Boyer-Moore 投票算法）&lt;/strong&gt;：核心思想是&amp;quot;正负抵消&amp;quot;。维护一个候选众数 &lt;code&gt;candidate&lt;/code&gt; 和一个计数器 &lt;code&gt;count&lt;/code&gt;。遍历数组：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;若 &lt;code&gt;count == 0&lt;/code&gt;，将当前元素设为候选。&lt;/li&gt;&#xA;&lt;li&gt;若当前元素等于 &lt;code&gt;candidate&lt;/code&gt;，&lt;code&gt;count++&lt;/code&gt;，否则 &lt;code&gt;count--&lt;/code&gt;。&#xA;由于众数数量超过一半，它最终会抵消掉所有非众数并留下来。&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;majorityElement&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; candidate &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0, count &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; num : 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;if&lt;/span&gt; (count &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; 0) candidate &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; num;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        count &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; (num &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; candidate) &lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt; 1 : &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; candidate;&#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(1)。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：抵消过程不关心具体抵消了谁，只关心票数差额。该算法只保证众数存在时正确（题目已保证）。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;3-颜色分类leetcode-75&#34;&gt;3. 颜色分类（LeetCode 75）&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;题目&lt;/strong&gt;：给定包含 0、1、2 的数组，原地排序，使所有 0 在前，1 居中，2 在后。不能使用库函数排序。&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;：维护三个指针：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;p0&lt;/code&gt;：指向下一个 0 应该放的位置（从左起）。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;p2&lt;/code&gt;：指向下一个 2 应该放的位置（从右起）。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;i&lt;/code&gt;：当前遍历指针。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;遍历时：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;若 &lt;code&gt;nums[i] == 0&lt;/code&gt;，交换 &lt;code&gt;i&lt;/code&gt; 和 &lt;code&gt;p0&lt;/code&gt;，&lt;code&gt;i++&lt;/code&gt;，&lt;code&gt;p0++&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;若 &lt;code&gt;nums[i] == 2&lt;/code&gt;，交换 &lt;code&gt;i&lt;/code&gt; 和 &lt;code&gt;p2&lt;/code&gt;，&lt;code&gt;p2--&lt;/code&gt;（注意 &lt;code&gt;i&lt;/code&gt; 不前进，因为换来的新值还需检查）。&lt;/li&gt;&#xA;&lt;li&gt;若 &lt;code&gt;nums[i] == 1&lt;/code&gt;，&lt;code&gt;i++&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;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sortColors&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; p0 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0, p2 &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;-&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; i &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; (i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; p2) {&#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;==&lt;/span&gt; 0) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            swap(nums, i, p0);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            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;            p0&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; (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; 2) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            swap(nums, i, p2);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            p2&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;            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;        }&#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;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;swap&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, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; j) {&#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; tmp &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;;&#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;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;j&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;j&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; tmp;&#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(1)。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：遇到 2 时 &lt;code&gt;i&lt;/code&gt; 不前进，因为从 &lt;code&gt;p2&lt;/code&gt; 换过来的元素可能是 0 或 1，需要下一轮继续处理。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;4-下一个排列leetcode-31&#34;&gt;4. 下一个排列（LeetCode 31）&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;题目&lt;/strong&gt;：给定整数数组，找出其按字典序排列的下一个更大的排列。若不存在（已是降序），则将其升序排列（最小的排列）。要求原地修改。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;技巧解法（字典序规律）&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;从右向左找第一个升序对 &lt;code&gt;(i, i+1)&lt;/code&gt;，满足 &lt;code&gt;nums[i] &amp;lt; nums[i+1]&lt;/code&gt;。此时 &lt;code&gt;i&lt;/code&gt; 右侧是降序序列。&lt;/li&gt;&#xA;&lt;li&gt;再从右向左找第一个大于 &lt;code&gt;nums[i]&lt;/code&gt; 的元素 &lt;code&gt;nums[j]&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;交换 &lt;code&gt;nums[i]&lt;/code&gt; 和 &lt;code&gt;nums[j]&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;将 &lt;code&gt;i+1&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;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;nextPermutation&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; i &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;-&lt;/span&gt; 2;&#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; (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;&amp;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;) 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:#66d9ef&#34;&gt;if&lt;/span&gt; (i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;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; j &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;-&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; (j &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;j&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&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;) j&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;        swap(nums, i, j);&#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;    reverse(nums, i &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; 1, nums.&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;}&#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;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;reverse&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, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; l, &lt;span style=&#34;color:#66d9ef&#34;&gt;int&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;while&lt;/span&gt; (l &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; r) swap(nums, l&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;}&#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(1)。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：找到第一个升序对是关键，它决定了可变动的最高位。若完全降序，直接反转整个数组。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;5-寻找重复数leetcode-287&#34;&gt;5. 寻找重复数（LeetCode 287）&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;题目&lt;/strong&gt;：给定包含 n+1 个整数的数组，数字都在 1~n 之间，只有一个数字重复出现（可能多次），找出这个重复数。要求不修改数组，且只用 O(1) 额外空间。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;常规思路&lt;/strong&gt;：二分答案（O(n log n)），或快慢指针。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;技巧解法（Floyd 判圈算法）&lt;/strong&gt;：将数组视为一个链表，其中 &lt;code&gt;i -&amp;gt; nums[i]&lt;/code&gt; 表示节点 &lt;code&gt;i&lt;/code&gt; 指向节点 &lt;code&gt;nums[i]&lt;/code&gt;。因为存在重复数，所以这个链表中必然存在环。我们使用快慢指针找到环的入口，入口节点就是重复的数字。&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; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;findDuplicate&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; slow &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0&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; fast &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0&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;do&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        slow &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;slow&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;        fast &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;fast&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;while&lt;/span&gt; (slow &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; fast);&#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;    slow &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;0&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;while&lt;/span&gt; (slow &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; fast) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        slow &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;slow&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;        fast &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; nums&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;fast&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; slow;&#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(1)。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：满足 &lt;code&gt;nums[i]&lt;/code&gt; 的范围在 &lt;code&gt;1~n&lt;/code&gt; 且数组长度 &lt;code&gt;n+1&lt;/code&gt;，才能保证将 &lt;code&gt;i&lt;/code&gt; 映射到 &lt;code&gt;nums[i]&lt;/code&gt; 不会越界（且 &lt;code&gt;0&lt;/code&gt; 不会出现在值中，所以从 &lt;code&gt;0&lt;/code&gt; 出发一定成环）。入口点就是被两个不同下标指向的值，即重复的数。&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;&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;136. 只出现一次的数字&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;169. 多数元素&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;75. 颜色分类&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;31. 下一个排列&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;287. 寻找重复数&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;Floyd 判圈（快慢指针）&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;p&gt;&lt;strong&gt;共同本质&lt;/strong&gt;：这些技巧题都摆脱了常规的&amp;quot;遍历存储&amp;quot;或&amp;quot;排序&amp;quot;思路，而是深入挖掘问题内在的 &lt;strong&gt;数学性质&lt;/strong&gt;（异或、众数票数）、&lt;strong&gt;数据结构关联&lt;/strong&gt;（数组视为链表）或 &lt;strong&gt;排列规则&lt;/strong&gt;（字典序），从而实现最优的时间和空间复杂度。&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;strong&gt;异或&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;看到&amp;quot;出现次数超过一半&amp;quot;，想到&lt;strong&gt;摩尔投票&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;看到&amp;quot;三类元素原地排序&amp;quot;，想到&lt;strong&gt;荷兰国旗&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;看到&amp;quot;字典序下一个&amp;quot;，记住&amp;quot;升序对 + 交换 + 反转&amp;quot;三步走。&lt;/li&gt;&#xA;&lt;li&gt;看到&amp;quot;n+1 个数在 1~n 之间找重复&amp;quot;，且不能改数组，想到 &lt;strong&gt;Floyd 判圈&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;</description>
        </item></channel>
</rss>
