<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>面试准备 on 方糖猫Blog</title>
    <link>https://ftmao.com/blog/tags/%E9%9D%A2%E8%AF%95%E5%87%86%E5%A4%87/</link>
    <description>AI 视频、AI Agent 与工程实践笔记</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Thu, 09 Aug 2018 11:04:39 +0800</lastBuildDate><atom:link href="https://ftmao.com/blog/tags/%E9%9D%A2%E8%AF%95%E5%87%86%E5%A4%87/index.xml" rel="self" type="application/rss+xml" /><item>
      <title>算法与数据结构入门学习总结：从零看懂核心原理与 LeetCode 避坑技巧</title>
      <link>https://ftmao.com/blog/posts/algorithm-and-data-structures-basics/</link>
      <pubDate>Thu, 09 Aug 2018 11:04:39 +0800</pubDate>
      <guid>https://ftmao.com/blog/posts/algorithm-and-data-structures-basics/</guid>
      <description>&lt;h1 id=&#34;算法与数据结构入门学习总结&#34;&gt;算法与数据结构入门学习总结&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;目标读者：刚开始刷题、想系统梳理基础的同学。&lt;br&gt;
参考文档：&lt;code&gt;D:\doc\算法\combined_document.md&lt;/code&gt;（《剑指 Offer（专项突破版）》题解合集）。&lt;br&gt;
阅读目标：理解核心原理、记住常用模板、少踩常见坑。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;0-写在前面为什么要先建立知识地图&#34;&gt;0. 写在前面：为什么要先建立“知识地图”&lt;/h2&gt;
&lt;p&gt;刷题最怕两种情况：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;拿到题完全没思路&lt;/strong&gt;，只能硬写暴力，时间超了也不知道怎么优化。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;大概知道方向，但细节错一堆&lt;/strong&gt;：数组越界、整数溢出、指针空指针、边界条件漏掉。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这篇博客想解决的就是这两个问题：&lt;strong&gt;先搭好知识框架，再集中火力避坑&lt;/strong&gt;。只要你知道“这道题可能考什么数据结构/算法思想”，就能快速定位解法。&lt;/p&gt;
&lt;h3 id=&#34;01-学习路线图&#34;&gt;0.1 学习路线图&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[语言基础] --&amp;gt; B[复杂度分析]
    B --&amp;gt; C[线性结构&amp;lt;br/&amp;gt;数组/链表/栈/队列]
    C --&amp;gt; D[非线性结构&amp;lt;br/&amp;gt;树/堆/图]
    D --&amp;gt; E[高级结构&amp;lt;br/&amp;gt;哈希/并查集/Trie]
    E --&amp;gt; F[基础算法思想]
    F --&amp;gt; G[专项刷题]
    F --&amp;gt; H[面试/竞赛]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;建议学习顺序&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先学 &lt;strong&gt;复杂度分析&lt;/strong&gt;，它是评判代码好坏的尺子。&lt;/li&gt;
&lt;li&gt;再学 &lt;strong&gt;数组、链表、栈、队列&lt;/strong&gt;，它们是后续所有结构的“建筑材料”。&lt;/li&gt;
&lt;li&gt;进入 &lt;strong&gt;树、堆、图&lt;/strong&gt;，理解非线性结构的遍历方式。&lt;/li&gt;
&lt;li&gt;最后系统学习 &lt;strong&gt;算法思想&lt;/strong&gt;：双指针、滑动窗口、二分、前缀和、回溯、动态规划、BFS/DFS。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;1-复杂度衡量算法的尺子&#34;&gt;1. 复杂度：衡量算法的尺子&lt;/h2&gt;
&lt;h3 id=&#34;11-时间复杂度&#34;&gt;1.1 时间复杂度&lt;/h3&gt;
&lt;p&gt;时间复杂度描述的是&lt;strong&gt;算法运行时间随输入规模增长的趋势&lt;/strong&gt;，不是真正的秒数。&lt;/p&gt;
&lt;p&gt;常见复杂度（从小到大）：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;复杂度&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;名称&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;典型场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(1)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;常数&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;哈希表查询、数组随机访问&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(log n)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;对数&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;二分查找、倍增&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(n)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;线性&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;一次遍历&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(n log n)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;线性对数&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;快排、归并排序&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(n²)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;平方&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;双重循环、朴素 DP&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(2ⁿ) / O(n!)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;指数/阶乘&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;回溯、全排列&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;估算口诀&lt;/strong&gt;：看循环层数 + 看每次循环内部有没有“折半”操作。&lt;/p&gt;
&lt;h3 id=&#34;12-空间复杂度&#34;&gt;1.2 空间复杂度&lt;/h3&gt;
&lt;p&gt;空间复杂度描述&lt;strong&gt;算法额外占用的内存&lt;/strong&gt;。注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;输入数组本身不计入额外空间。&lt;/li&gt;
&lt;li&gt;递归调用栈深度也要算空间。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[分析代码] --&amp;gt; B[有没有开辟新数组/哈希表?]
    A --&amp;gt; C[有没有递归?]
    B --&amp;gt; D[空间 = 数据结构大小]
    C --&amp;gt; E[空间 = 递归最大深度]
    D --&amp;gt; F[取最大值]
    E --&amp;gt; F&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;2-数据结构全景图&#34;&gt;2. 数据结构全景图&lt;/h2&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;mindmap
  root((数据结构与算法))
    线性结构
      数组
      链表
      栈
      队列
    非线性结构
      树
        二叉树
        二叉搜索树
      堆
      图
    集合与映射
      哈希表
      并查集
    字符串专属
      前缀树 Trie
    算法思想
      双指针/滑动窗口
      二分/前缀和
      递归/回溯
      动态规划
      贪心/分治&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;21-各数据结构的核心能力&#34;&gt;2.1 各数据结构的核心能力&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;数据结构&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;核心能力&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;最适合解决的问题&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;数组&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;随机访问 O(1)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;按索引查询、前缀和、双指针&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;链表&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;动态增删 O(1)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;反转、合并、环检测&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;栈&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;后进先出 LIFO&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;括号匹配、表达式求值、单调栈&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;队列&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;先进先出 FIFO&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;BFS、滑动窗口、单调队列&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;哈希表&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;快速查找 O(1)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;去重、计数、两数之和&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;树/ BST&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;分层、有序&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;遍历、最近公共祖先、中序有序&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;堆&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;快速取最值 O(log n)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;TopK、合并 K 个有序数组&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;图&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;描述多对多关系&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;最短路径、拓扑排序、连通性&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;Trie&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;前缀匹配&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;单词前缀、最大异或、自动补全&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;3-线性结构数组链表栈队列&#34;&gt;3. 线性结构：数组、链表、栈、队列&lt;/h2&gt;
&lt;h3 id=&#34;31-数组最朴素但最万能&#34;&gt;3.1 数组：最朴素但最万能&lt;/h3&gt;
&lt;p&gt;数组的特点是&lt;strong&gt;连续内存 + 随机访问&lt;/strong&gt;。数组题最常见的套路是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;双指针&lt;/strong&gt;：相向（两数之和）、同向（滑动窗口）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;前缀和&lt;/strong&gt;：把“区间求和”变成“两个前缀和相减”。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排序后处理&lt;/strong&gt;：很多题先排序，复杂度就从 O(n²) 降到 O(n log n)。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;双指针模板&#34;&gt;双指针模板&lt;/h4&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[初始化 left, right] --&amp;gt; B{指针方向?}
    B --&amp;gt;|相向| C[left=0, right=n-1]
    B --&amp;gt;|同向| D[left=0, right=0]
    C --&amp;gt; E[while left &amp;lt; right]
    D --&amp;gt; F[for right in 0..n-1]
    E --&amp;gt; G[根据条件移动 left 或 right]
    F --&amp;gt; H[按需收缩 left 扩展窗口]
    G --&amp;gt; I[更新答案]
    H --&amp;gt; I&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;例题思路串讲&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;题目&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;核心技巧&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;关键记忆点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;排序数组中两数之和&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;相向双指针&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;和大了 &lt;code&gt;right--&lt;/code&gt;，和小了 &lt;code&gt;left++&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;三数之和&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;排序 + 双指针 + 去重&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;外层和内层都要 &lt;code&gt;while&lt;/code&gt; 跳过重复值&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;和 ≥ target 的最短子数组&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;同向双指针/滑动窗口&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;右扩左缩，记录最小长度&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;乘积 &amp;lt; K 的子数组&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;同向双指针&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;满足条件时新增 &lt;code&gt;right-left+1&lt;/code&gt; 个子数组&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;和为 K 的子数组&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;前缀和 + 哈希表&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;map.put(0, 1)&lt;/code&gt; 必不可少&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;0 和 1 个数相同的子数组&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;0 变 -1 后转“和为 0”&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;map.put(0, -1)&lt;/code&gt; 处理从开头开始的子数组&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;二维子矩阵的和&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;二维前缀和&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;sum[i+1][j+1] = sum[i][j+1] + rowSum&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;三数之和去重是新人重灾区&lt;/strong&gt;，一定要记住：排序后，如果当前值和上一个值相同，就跳过，否则会产生重复三元组。&lt;/p&gt;
&lt;h3 id=&#34;32-链表虚拟头节点--快慢指针&#34;&gt;3.2 链表：虚拟头节点 + 快慢指针&lt;/h3&gt;
&lt;p&gt;链表不像数组能随机访问，所以核心技巧是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;虚拟头节点（dummy）&lt;/strong&gt;：方便删除头节点，统一代码。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;快慢指针&lt;/strong&gt;：找中点、找环、找倒数第 K 个。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;反转链表&lt;/strong&gt;：三指针 &lt;code&gt;pre / now / next&lt;/code&gt; 一遍完成。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &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:#75715e&#34;&gt;// 反转链表模板&lt;/span&gt;
&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; ListNode &lt;span style=&#34;color:#a6e22e&#34;&gt;reverseList&lt;/span&gt;(ListNode head) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ListNode pre &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;, now &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; head;
&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; (now &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&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ListNode next &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; now.&lt;span style=&#34;color:#a6e22e&#34;&gt;next&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        now.&lt;span style=&#34;color:#a6e22e&#34;&gt;next&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; pre;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pre &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; now;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        now &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; next;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&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; pre;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;链表常见坑&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;忘记处理空链表或单节点。&lt;/li&gt;
&lt;li&gt;移动指针时把 &lt;code&gt;next&lt;/code&gt; 覆盖了，后面没法继续遍历。&lt;/li&gt;
&lt;li&gt;找中点时快慢指针初始化/终止条件写错（建议画图手推一次）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;33-栈后进先出--单调栈&#34;&gt;3.3 栈：后进先出 + 单调栈&lt;/h3&gt;
&lt;p&gt;栈的两个高频用法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;辅助计算&lt;/strong&gt;：括号匹配、后缀表达式、进制转换。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;单调栈&lt;/strong&gt;：找“下一个更大/更小元素”、直方图最大矩形。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[遍历元素] --&amp;gt; B{栈顶与新元素关系?}
    B --&amp;gt;|满足单调性| C[压栈]
    B --&amp;gt;|破坏单调性| D[弹出栈顶并计算]
    D --&amp;gt; B
    C --&amp;gt; E[继续遍历]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;34-队列先进先出--bfs-利器&#34;&gt;3.4 队列：先进先出 + BFS 利器&lt;/h3&gt;
&lt;p&gt;队列最经典的应用是 &lt;strong&gt;BFS（广度优先搜索）&lt;/strong&gt;：一层一层扩展，天然适合“最短路径/最浅结果”。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[起点入队] --&amp;gt; B[while 队列非空]
    B --&amp;gt; C[队首出队]
    C --&amp;gt; D[扩展所有邻居]
    D --&amp;gt; E[未访问的邻居入队]
    E --&amp;gt; B&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;4-非线性结构树堆图&#34;&gt;4. 非线性结构：树、堆、图&lt;/h2&gt;
&lt;h3 id=&#34;41-二叉树递归是王道&#34;&gt;4.1 二叉树：递归是王道&lt;/h3&gt;
&lt;p&gt;二叉树题目 90% 都能用递归解决，核心想清楚三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;当前节点要做什么？&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;递归返回什么？&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;边界条件是什么？&lt;/strong&gt;（通常是 &lt;code&gt;node == null&lt;/code&gt;）&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[处理当前节点] --&amp;gt; B[递归左子树]
    A --&amp;gt; C[递归右子树]
    B --&amp;gt; D[合并左右结果]
    C --&amp;gt; D&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;二叉树遍历&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前序：根 → 左 → 右&lt;/li&gt;
&lt;li&gt;中序：左 → 根 → 右（BST 中序有序）&lt;/li&gt;
&lt;li&gt;后序：左 → 右 → 根&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;二叉搜索树（BST）性质&lt;/strong&gt;：左子树所有节点 &amp;lt; 根 &amp;lt; 右子树所有节点。利用这个性质可以 O(h) 查找、插入、删除。&lt;/p&gt;
&lt;h3 id=&#34;42-堆优先队列--动态最值&#34;&gt;4.2 堆：优先队列 = 动态最值&lt;/h3&gt;
&lt;p&gt;堆通常用优先队列实现。核心能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插入 O(log n)&lt;/li&gt;
&lt;li&gt;取最值 O(log n)&lt;/li&gt;
&lt;li&gt;看最值 O(1)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;TopK 问题&lt;/strong&gt;（找前 K 大/小）是堆最经典的面试题。思路：维护一个大小为 K 的小根堆，堆里保存目前最大的 K 个数。&lt;/p&gt;
&lt;h3 id=&#34;43-图bfs-vs-dfs&#34;&gt;4.3 图：BFS vs DFS&lt;/h3&gt;
&lt;p&gt;图是最灵活的数据结构，几乎所有图算法都基于 &lt;strong&gt;BFS&lt;/strong&gt; 或 &lt;strong&gt;DFS&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[图的遍历] --&amp;gt; B{要最短/分层?}
    B --&amp;gt;|是| C[BFS 队列]
    B --&amp;gt;|否| D[DFS 递归/栈]
    C --&amp;gt; E[visited 集合防重复]
    D --&amp;gt; E&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;图的常见题型&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;问题&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;首选算法&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;岛屿数量、连通分量&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;DFS / 并查集&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;最短路径（无权图）&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;BFS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;拓扑排序&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;Kahn 算法（入度）/ DFS 后序逆序&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;最小生成树&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;Kruskal / Prim&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;单源最短路（带权）&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;Dijkstra / Bellman-Ford&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;5-高级结构与技巧&#34;&gt;5. 高级结构与技巧&lt;/h2&gt;
&lt;h3 id=&#34;51-哈希表用空间换时间&#34;&gt;5.1 哈希表：用空间换时间&lt;/h3&gt;
&lt;p&gt;哈希表能把“查找”从 O(n) 降到 O(1)。刷题时常见的哈希用法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;计数&lt;/strong&gt;：统计字符/数字出现次数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;去重&lt;/strong&gt;：判断元素是否出现过。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;记录位置&lt;/strong&gt;：LRU、两数之和、前缀和下标。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;经典设计题&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;RandomizedSet&lt;/strong&gt;：数组 + 哈希表，删除时把末尾元素 swap 到被删位置，保证 O(1)。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LRU Cache&lt;/strong&gt;：哈希表 + 双向链表，get/put 都把节点移到尾部，超出容量时删头部。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;52-前缀树-trie&#34;&gt;5.2 前缀树 Trie&lt;/h3&gt;
&lt;p&gt;Trie 用于高效处理字符串前缀、自动补全、最大异或等问题。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[root] --&amp;gt; B[a]
    A --&amp;gt; C[b]
    B --&amp;gt; D[p]
    B --&amp;gt; E[p2]
    C --&amp;gt; F[e]
    D --&amp;gt; G[p&amp;lt;br/&amp;gt;isEnd=true]
    E --&amp;gt; H[p&amp;lt;br/&amp;gt;isEnd=true]
    F --&amp;gt; I[e&amp;lt;br/&amp;gt;isEnd=true]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;每个节点代表一个字符前缀；叶子或标记节点表示完整单词。&lt;/p&gt;
&lt;h3 id=&#34;53-并查集&#34;&gt;5.3 并查集&lt;/h3&gt;
&lt;p&gt;并查集解决“连通性”问题，三个操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;find(x)&lt;/code&gt;：找到 x 的根。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;union(x, y)&lt;/code&gt;：合并两个集合。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;connected(x, y)&lt;/code&gt;：判断是否同根。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;配合 &lt;strong&gt;路径压缩&lt;/strong&gt; 和 &lt;strong&gt;按秩合并&lt;/strong&gt;，单次操作近似 O(α(n))，可以认为接近 O(1)。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;6-算法思想把题归类&#34;&gt;6. 算法思想：把题归类&lt;/h2&gt;
&lt;h3 id=&#34;61-二分查找不是只能查有序数组&#34;&gt;6.1 二分查找：不是只能查有序数组&lt;/h3&gt;
&lt;p&gt;二分查找的精髓是：&lt;strong&gt;找到一个可以判定“答案是否可行”的条件&lt;/strong&gt;，然后不断缩小答案区间。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[确定二分对象] --&amp;gt; B[写出 canmid 判定]
    B --&amp;gt; C[初始化 l, r]
    C --&amp;gt; D[while l &amp;lt; r]
    D --&amp;gt; E{canmid?}
    E --&amp;gt;|true| F[答案在左半区&amp;lt;br/&amp;gt;r = mid]
    E --&amp;gt;|false| G[答案在右半区&amp;lt;br/&amp;gt;l = mid + 1]
    F --&amp;gt; D
    G --&amp;gt; D
    D --&amp;gt; H[返回 l]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;二分查找避坑&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;循环条件写成 &lt;code&gt;l &amp;lt;= r&lt;/code&gt; 还是 &lt;code&gt;l &amp;lt; r&lt;/code&gt;，取决于你要不要包含右端点。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mid = l + (r - l) / 2&lt;/code&gt; 比 &lt;code&gt;(l + r) / 2&lt;/code&gt; 更安全，防止整数溢出。&lt;/li&gt;
&lt;li&gt;左/右边界更新要对称：左闭右闭就 &lt;code&gt;l = mid + 1, r = mid - 1&lt;/code&gt;；左闭右开要相应调整。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;62-滑动窗口双指针的高级形态&#34;&gt;6.2 滑动窗口：双指针的高级形态&lt;/h3&gt;
&lt;p&gt;滑动窗口适合处理&lt;strong&gt;子数组/子串&lt;/strong&gt;问题，前提是“右指针右移时，窗口内某种性质单调变化”。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[初始化 left=0] --&amp;gt; B[right 从左到右遍历]
    B --&amp;gt; C[扩大窗口 更新状态]
    C --&amp;gt; D{窗口是否合法?}
    D --&amp;gt;|不合法| E[移动 left 收缩窗口]
    D --&amp;gt;|合法| F[更新答案]
    E --&amp;gt; F
    F --&amp;gt; B&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;什么时候不能用滑动窗口？&lt;/strong&gt; 当数组不是单调（例如有负数）时，和/积不具备单调性，要改用前缀和 + 哈希表。&lt;/p&gt;
&lt;h3 id=&#34;63-前缀和区间查询的利器&#34;&gt;6.3 前缀和：区间查询的利器&lt;/h3&gt;
&lt;p&gt;前缀和把“区间和”问题变成“差分”：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sum(i, j) = prefix[j+1] - prefix[i]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;二维前缀和公式：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;prefix[i][j] = matrix[i-1][j-1]
             + prefix[i-1][j] + prefix[i][j-1]
             - prefix[i-1][j-1]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;一维前缀和 + 哈希表&lt;/strong&gt; 可以把“和为 K 的子数组”从 O(n²) 降到 O(n)。&lt;/p&gt;
&lt;h3 id=&#34;64-递归与回溯暴力枚举的艺术&#34;&gt;6.4 递归与回溯：暴力枚举的艺术&lt;/h3&gt;
&lt;p&gt;回溯 = 递归 + 做选择 + 撤销选择。模板：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &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;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;backtrack&lt;/span&gt;(路径, 选择列表) {
&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; (满足结束条件) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        result.&lt;span style=&#34;color:#a6e22e&#34;&gt;add&lt;/span&gt;(路径);
&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;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&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; (选择 in 选择列表) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        做选择;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        backtrack(路径, 选择列表);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        撤销选择;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TD
    A[开始 backtrack] --&amp;gt; B{剪枝/终止?}
    B --&amp;gt;|是| C[记录答案]
    B --&amp;gt;|否| D[做选择]
    D --&amp;gt; E[递归下一层]
    E --&amp;gt; F[撤销选择]
    F --&amp;gt; G[尝试下一个选择]
    G --&amp;gt; D
    C --&amp;gt; H[返回]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;回溯常见题型&lt;/strong&gt;：子集、组合、排列、N 皇后、括号生成、复原 IP。&lt;/p&gt;
&lt;h3 id=&#34;65-动态规划找状态转移&#34;&gt;6.5 动态规划：找状态转移&lt;/h3&gt;
&lt;p&gt;DP 是很多新人的噩梦。其实套路很固定：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[&amp;#34;定义状态 dp[i] 或 dp[i][j]&amp;#34;] --&amp;gt; B[写状态转移方程]
    B --&amp;gt; C[确定初始状态]
    C --&amp;gt; D[确定遍历顺序]
    D --&amp;gt; E[空间优化可选]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;入门 DP 分类&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;类型&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;特征&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;例题&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;线性 DP&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;一维数组递推&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;爬楼梯、房屋偷盗、最长递增子序列&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;区间 DP&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;区间 [i,j] 状态&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;最长回文子序列、最少回文分割&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;背包 DP&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;选或不选&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;分割等和子集、最少硬币&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;路径 DP&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;二维网格&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;不同路径、最小路径和&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;状态压缩 DP&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;用二进制表示集合&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;旅行商问题、棋盘覆盖&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;DP 避坑&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;状态定义不清晰就开始写，写到一半发现转移不了。&lt;/li&gt;
&lt;li&gt;遍历顺序搞反，导致用到还没计算出来的状态。&lt;/li&gt;
&lt;li&gt;忘记初始化 &lt;code&gt;dp[0]&lt;/code&gt; 或边界行/列。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;66-贪心每次局部最优&#34;&gt;6.6 贪心：每次局部最优&lt;/h3&gt;
&lt;p&gt;贪心没有通用模板，关键是&lt;strong&gt;证明局部最优能推导出全局最优&lt;/strong&gt;。常见贪心场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;区间问题：按结束时间排序选最多不重叠区间。&lt;/li&gt;
&lt;li&gt;跳跃游戏：每次选能跳最远的位置。&lt;/li&gt;
&lt;li&gt;哈夫曼编码：每次合并最小的两个。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你不确定贪心对不对，建议先用 DP 或回溯验证小例子。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;7-位运算与整数技巧&#34;&gt;7. 位运算与整数技巧&lt;/h2&gt;
&lt;p&gt;参考文档第一章专门讲整数，里面有很多位运算技巧，面试题也常考。&lt;/p&gt;
&lt;h3 id=&#34;71-常用位运算技巧&#34;&gt;7.1 常用位运算技巧&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;技巧&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;含义&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;例题&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;n &amp;amp; (n-1)&lt;/code&gt;&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;把 n 最右侧的 1 变成 0&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;统计二进制 1 的个数&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;n &amp;amp; (-n)&lt;/code&gt;&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;只保留最右侧的 1&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;判断是否是 2 的幂&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;a ^ a = 0&lt;/code&gt;&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;相同数异或为 0&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;只出现一次的数字&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;a ^ 0 = a&lt;/code&gt;&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;与 0 异或不变&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;两数交换&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;72-整数除法倍增法&#34;&gt;7.2 整数除法：倍增法&lt;/h3&gt;
&lt;p&gt;最朴素的除法是不断减，最坏 O(n)。倍增法的思想是：判断被除数能容纳除数的 1 倍、2 倍、4 倍……直到不能容纳，然后减去最大的倍数，重复这个过程。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;复杂度&lt;/strong&gt;：O(log n)。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;避坑&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Integer.MIN_VALUE / -1&lt;/code&gt; 会溢出。&lt;/li&gt;
&lt;li&gt;为了处理符号，通常把两个数都转成负数计算，最后再加符号。&lt;/li&gt;
&lt;li&gt;累加时要判断是否超过 &lt;code&gt;0xc0000000&lt;/code&gt;（即最小负数的一半），防止溢出。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;73-状态压缩用-int-表示集合&#34;&gt;7.3 状态压缩：用 int 表示集合&lt;/h3&gt;
&lt;p&gt;当数据范围只有 26 个小写字母、或 20 个以内的元素时，可以用一个 int 的每一位表示“选/没选”。&lt;/p&gt;
&lt;p&gt;例如“单词长度的最大乘积”中，用 int 的低 26 位表示一个单词包含哪些字母，两个单词的位掩码 &lt;code&gt;&amp;amp;&lt;/code&gt; 为 0 就说明没有公共字母。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;8-排序算法回顾&#34;&gt;8. 排序算法回顾&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;排序&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;平均时间&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;空间&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;稳定性&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;冒泡/选择/插入&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(n²)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(1)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;稳定（插入）&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;简单，数据量小可用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;快速排序&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(n log n)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(log n)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;不稳定&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;平均最快&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;归并排序&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(n log n)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(n)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;稳定&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;链表排序、逆序对&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;堆排序&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(n log n)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(1)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;不稳定&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;TopK、优先队列&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;计数/桶/基数&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(n+k)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;O(k)&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;稳定&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;数据范围有限&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;实战建议&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数组排序直接用语言内置函数（Java &lt;code&gt;Arrays.sort()&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;链表排序适合归并（自顶向下或自底向上）。&lt;/li&gt;
&lt;li&gt;找第 K 大可以用快速选择（平均 O(n)）或堆。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;9-leetcode-刷题闭坑指南重点&#34;&gt;9. LeetCode 刷题闭坑指南（重点）&lt;/h2&gt;
&lt;p&gt;这部分把参考文档里反复出现的“坑”集中整理出来，刷题前先看一遍，能少错很多。&lt;/p&gt;
&lt;h3 id=&#34;91-拿到题后先做什么&#34;&gt;9.1 拿到题后先做什么&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[拿到题目] --&amp;gt; B[读三遍题意]
    B --&amp;gt; C[列出所有边界条件]
    C --&amp;gt; D[手写 2-3 个小例子]
    D --&amp;gt; E[判断数据结构与算法]
    E --&amp;gt; F[写代码]
    F --&amp;gt; G[脑内跑一遍边界]
    G --&amp;gt; H[提交]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;92-整数与边界&#34;&gt;9.2 整数与边界&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;坑&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;案例&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;整数溢出&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;Integer.MIN_VALUE / -1&lt;/code&gt; 返回 &lt;code&gt;Integer.MAX_VALUE&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;越界累加&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;除法倍增时判断 &lt;code&gt;value &amp;gt;= 0xc0000000&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;负数右移&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;负数算术右移最高位永远补 1&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;mid&lt;/code&gt; 溢出&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;二分写 &lt;code&gt;mid = l + (r - l) / 2&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;93-数组与字符串&#34;&gt;9.3 数组与字符串&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;坑&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;案例&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;下标越界&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;right = n&lt;/code&gt; 还是 &lt;code&gt;right = n-1&lt;/code&gt; 要统一&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;左/右边界更新&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;注意是 &lt;code&gt;++left&lt;/code&gt; 还是 &lt;code&gt;left++&lt;/code&gt;（三数之和去重用 &lt;code&gt;nums[++left]&lt;/code&gt;）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;前缀和初始化&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;和为 K 子数组必须 &lt;code&gt;map.put(0, 1)&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;二维前缀和&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;通常多开一行一列避免边界判断&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;字符串变位词&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;用长度 26/58 的 int 数组模拟哈希表&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;94-链表&#34;&gt;9.4 链表&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;坑&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;解决方案&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;头节点可能被删&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;使用 dummy 节点&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;空指针&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;访问 &lt;code&gt;node.next&lt;/code&gt; 前先判空&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;找中点/环&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;快慢指针初始化和终止条件画图确认&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;反转丢失 next&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;先用临时变量保存 &lt;code&gt;now.next&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;95-递归与回溯&#34;&gt;9.5 递归与回溯&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;坑&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;解决方案&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;终止条件漏写&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;先写边界，再写递归体&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;共享状态被污染&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;回溯时记得“撤销选择”&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;重复结果&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;排序后跳过相同元素，或用 &lt;code&gt;visited&lt;/code&gt; 数组&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;栈溢出&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;深度太大时考虑改迭代 + 栈&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;96-动态规划&#34;&gt;9.6 动态规划&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;坑&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;解决方案&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;状态定义错误&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;先用一句话描述“dp[i] 表示什么”&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;遍历顺序错误&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;画依赖图，确保计算 dp[i] 时所需状态已算好&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;边界没初始化&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;先填第 0 行/列，或 &lt;code&gt;dp[0]&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;空间可以优化&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;滚动数组、一维降维&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;97-二分查找&#34;&gt;9.7 二分查找&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;坑&lt;/th&gt;
					&lt;th style=&#34;text-align: left&#34;&gt;解决方案&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;循环条件写错&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;根据开闭区间选择 &lt;code&gt;l &amp;lt; r&lt;/code&gt; 或 &lt;code&gt;l &amp;lt;= r&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;边界更新不对称&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;&lt;code&gt;l = mid + 1&lt;/code&gt; 对应 &lt;code&gt;r = mid&lt;/code&gt; 或 &lt;code&gt;r = mid - 1&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;死循环&lt;/td&gt;
					&lt;td style=&#34;text-align: left&#34;&gt;左中点 &lt;code&gt;mid = l + (r-l)/2&lt;/code&gt; 与右中点 &lt;code&gt;mid = l + (r-l+1)/2&lt;/code&gt; 选清楚&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;10-一张图串联所有知识点&#34;&gt;10. 一张图串联所有知识点&lt;/h2&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[算法题] --&amp;gt; B{看到什么关键词?}
    B --&amp;gt;|子数组/子串&amp;lt;br/&amp;gt;和/积/去重| C[双指针 / 滑动窗口]
    B --&amp;gt;|区间和/连续和| D[前缀和 + 哈希表]
    B --&amp;gt;|有序 / 最大化最小值| E[二分查找]
    B --&amp;gt;|所有组合/排列/子集| F[回溯]
    B --&amp;gt;|最优子结构| G[动态规划]
    B --&amp;gt;|最短路径/层序| H[BFS]
    B --&amp;gt;|连通/全遍历| I[DFS / 并查集]
    B --&amp;gt;|TopK / 动态最值| J[堆]
    B --&amp;gt;|前缀匹配| K[Trie]
    C --&amp;gt; L[写代码]
    D --&amp;gt; L
    E --&amp;gt; L
    F --&amp;gt; L
    G --&amp;gt; L
    H --&amp;gt; L
    I --&amp;gt; L
    J --&amp;gt; L
    K --&amp;gt; L&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;11-给新人的刷题路线建议&#34;&gt;11. 给新人的刷题路线建议&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;第 1-2 周：数组 + 链表&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;两数之和、三数之和、反转链表、合并两个有序链表、环形链表。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 3-4 周：栈 + 队列 + 哈希表&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;有效的括号、最小栈、LRU 缓存、字母异位词。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 5-6 周：树 + 递归&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;二叉树前中后序遍历、二叉树层序遍历、二叉搜索树验证、路径总和。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 7-8 周：回溯 + 动态规划&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;全排列、组合总和、爬楼梯、最长公共子序列、不同路径。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第 9-10 周：图 + 高级结构&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;岛屿数量、课程表（拓扑排序）、数据流第 K 大、实现 Trie。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;持续：按标签二刷 + 总结错题本&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;刷题原则&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一遍不要死磕，20 分钟没思路直接看题解，重点理解“为什么这样想”。&lt;/li&gt;
&lt;li&gt;第二天再独立写一遍，一周后回来再写一遍。&lt;/li&gt;
&lt;li&gt;把每道题的“思路关键词”写进错题本，考前只看错题本。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;12-结语&#34;&gt;12. 结语&lt;/h2&gt;
&lt;p&gt;算法和数据结构不是背代码，而是建立**“看到题目 → 识别模式 → 套用模板 → 处理边界”**的条件反射。希望这篇总结能帮你把零散的知识点串成一张网，刷题时少踩坑、多 AC。&lt;/p&gt;
&lt;p&gt;最后送一句话：&lt;strong&gt;慢即是快&lt;/strong&gt;。把一类题真正搞懂，比囫囵吞枣刷一百道更有效。&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;参考文档：`（《剑指 Offer（专项突破版）》题解合集）。&lt;br&gt;
本文已整理成博客，欢迎在留言区补充你踩过的坑。&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    
  </channel>
</rss>
