LeetCode 算法思维训练指南
写给算法工程师的话
作为一位经验丰富的工程师,你已经具备了扎实的编程基础和工程思维。本指南的目标不是教你编程,而是帮助你建立算法题的思维模式,避免在细节中迷失,专注于问题的本质。
我们将重点关注 LeetCode 的 Medium 难度题目,这类题目最能考察算法思维的灵活运用,也是面试中的主流难度。
核心理念
- 简化优于优化:先找到清晰的解决方案,再考虑优化
- 模式识别:大多数算法题都有固定的模式,关键是识别和转化
- 代数思维:利用你的数学背景,用代数和矩阵的角度理解问题
- 函数式思维:递归和不可变性往往能让问题更清晰
章节安排
第一部分:思维基础
第1章:算法思维与复杂度分析
建立正确的思维框架,避免过度复杂化
- 算法题的本质:约束条件下的优化
- 复杂度直觉:根据数据规模判断可行解法
- 简化思维:从暴力到优化的系统路径 (#215 数组中第K大元素)
- 调试思维:快速定位逻辑错误
第2章:数组与哈希表的巧妙运用
最基础也最灵活的数据结构
- 数组索引的多重含义与原地操作 (#41 缺失的第一个正数, #287 寻找重复数)
- 哈希表的三种核心用法:去重、计数、映射 (#49 字母异位词分组, #128 最长连续序列)
- 前缀和与差分数组:区间操作优化 (#560 和为K的子数组, #238 除自身以外数组的乘积)
- 滑动窗口与双指针模板 (#3 无重复字符的最长子串, #15 三数之和)
第二部分:核心技巧
第3章:双指针与滑动窗口
线性时间的艺术
- 相向双指针:有序数组的利用 (#11 盛最多水的容器, #16 最接近的三数之和)
- 快慢指针:链表与数组去重 (#142 环形链表II, #80 删除有序数组中的重复项II)
- 滑动窗口:最长/最短子串问题 (#209 长度最小的子数组, #438 找到字符串中所有字母异位词)
- 多指针协作:三数之和、四数之和 (#15 三数之和, #18 四数之和)
第4章:二分查找的变体
对数时间的威力
- 标准二分与边界处理 (#34 在排序数组中查找元素的第一个和最后一个位置)
- 二分答案:最大化最小值问题 (#875 爱吃香蕉的珂珂, #1011 在D天内送达包裹的能力)
- 旋转数组与山峰数组 (#33 搜索旋转排序数组, #162 寻找峰值)
- 二分查找的抽象:单调性与决策函数 (#287 寻找重复数, #378 有序矩阵中第K小的元素)
第5章:栈与单调栈
维护有序性的利器
- 栈的基本应用:括号匹配、表达式求值 (#71 简化路径, #150 逆波兰表达式求值)
- 单调栈:下一个更大/更小元素 (#739 每日温度, #503 下一个更大元素II)
- 最大矩形与柱状图问题 (#84 柱状图中最大的矩形, #85 最大矩形)
- 栈与递归的关系 (#394 字符串解码, #341 扁平化嵌套列表迭代器)
第三部分:递归与搜索
第6章:树的递归思维
自相似结构的优雅处理
- 递归三要素:终止条件、递归体、返回值 (#236 二叉树的最近公共祖先, #114 二叉树展开为链表)
- 自顶向下vs自底向上 (#543 二叉树的直径, #124 二叉树中的最大路径和)
- 路径问题:从根到叶、任意路径 (#113 路径总和II, #437 路径总和III)
- 树的序列化与构造 (#297 二叉树的序列化与反序列化, #105 从前序与中序遍历序列构造二叉树)
第7章:回溯与剪枝
搜索空间的系统探索
- 回溯模板:选择、探索、撤销 (#46 全排列, #216 组合总和III)
- 排列组合子集问题 (#90 子集II, #47 全排列II, #491 递增子序列)
- N皇后与数独:约束满足 (#51 N皇后, #37 解数独)
- 剪枝技巧:可行性与最优性剪枝 (#39 组合总和, #40 组合总和II)
第8章:BFS与DFS的选择
图遍历的两种视角
- BFS:最短路径与层序遍历 (#103 二叉树的锯齿形层序遍历, #127 单词接龙)
- DFS:连通性与拓扑排序 (#200 岛屿数量, #207 课程表)
- 双向BFS优化 (#126 单词接龙II, #752 打开转盘锁)
- 记忆化搜索:DFS+缓存 (#329 矩阵中的最长递增路径, #139 单词拆分)
第四部分:动态规划
第9章:动态规划的本质
从递归到记忆化到迭代
- 重叠子问题与最优子结构 (#96 不同的二叉搜索树, #95 不同的二叉搜索树II)
- 状态定义的艺术 (#198 打家劫舍, #337 打家劫舍III)
- 递推vs递归:两种实现方式 (#63 不同路径II, #64 最小路径和)
- 空间优化:滚动数组与状态压缩 (#309 最佳买卖股票时机含冷冻期, #714 买卖股票的最佳时机含手续费)
第10章:背包问题家族
DP的经典模式
- 01背包:选或不选的决策 (#416 分割等和子集, #494 目标和)
- 完全背包:无限使用的优化 (#322 零钱兑换, #518 零钱兑换II)
- 多重背包与分组背包 (#474 一和零)
- 背包的变体:恰好装满、方案计数 (#377 组合总和IV, #139 单词拆分)
第11章:区间DP与状态压缩
高级DP技巧
- 区间DP:戳气球、矩阵链乘法 (#312 戳气球, #1039 多边形三角剖分的最低得分)
- 数位DP:统计特定范围内的数 (#233 数字1的个数, #902 最大为N的数字组合)
- 状态压缩:用二进制表示集合 (#464 我能赢吗, #847 访问所有节点的最短路径)
- 概率DP与期望DP (#688 骑士在棋盘上的概率, #837 新21点)
第五部分:高级主题
第12章:图算法精选
复杂关系的建模与处理
- 图的表示:邻接表vs邻接矩阵 (#133 克隆图, #310 最小高度树)
- 最短路径:Dijkstra、Bellman-Ford (#743 网络延迟时间, #787 K站中转内最便宜的航班)
- 最小生成树:Kruskal、Prim (#1584 连接所有点的最小费用, #1168 水资源分配优化)
- 并查集:连通性与等价类 (#684 冗余连接, #721 账户合并)
第13章:贪心算法的正确性
局部最优到全局最优
- 贪心选择性质的证明 (#55 跳跃游戏, #45 跳跃游戏II)
- 区间调度与活动选择 (#435 无重叠区间, #452 用最少数量的箭引爆气球)
- 哈夫曼编码与最优合并 (#1167 连接木棍的最低费用, #253 会议室II)
- 贪心的反例与陷阱 (#406 根据身高重建队列, #621 任务调度器)
第14章:数学与位运算技巧
巧妙的数学洞察
- 位运算:异或的妙用、位掩码技巧 (#137 只出现一次的数字II, #260 只出现一次的数字III)
- 数论基础:GCD、质数、模运算 (#166 分数到小数, #50 Pow(x, n))
- 组合数学:排列组合公式的应用 (#31 下一个排列, #60 排列序列)
- 几何问题:凸包、最近点对 (#149 直线上最多的点数, #223 矩形面积)
使用建议
- 循序渐进:每章都建立在前面的基础上
- 重视思路:理解"为什么这样想"比"怎么实现"更重要
- 练习反思:做题后总结模式,而不是记忆具体解法
- AI辅助:善用AI工具理解题意和验证思路,但要自己完成核心推理
学习目标
完成本指南后,你应该能够:
- 快速识别题目类型和适用的算法模式
- 避免常见的思维陷阱和过度复杂化
- 在30-45分钟内解决大部分Medium难度题目
- 清晰地解释你的思路和权衡
让我们开始这段算法思维的修炼之旅。