一、前言
经过前面 11 个模块、15 篇文章的系统学习,我们已经完成了 LeetCode 热门 100 题的全覆盖。从最基础的哈希表到最复杂的多维动态规划,从线性的数组链表到非线性的图论和回溯,每一道题都对应一种特定的算法思想或数据结构技巧。
本文旨在对全部模块进行 横向对比与纵向串联,帮助你在脑海中形成一张完整的"算法知识图谱"。当遇到新题目时,能够快速匹配到对应的解题范式。
二、算法模块全景图
LeetCode 热门 100 题的算法模块可以按照 数据结构 和 算法思想 两个维度进行分类:
按数据结构分类
| 模块 | 核心数据结构 | 代表题目 |
|---|---|---|
| 哈希表 | HashMap / HashSet | 两数之和、字母异位词分组、最长连续序列 |
| 栈 | Deque(ArrayDeque) | 有效的括号、最小栈、字符串解码、每日温度 |
| 堆(优先队列) | PriorityQueue | 第K大元素、前K高频元素、数据流中位数 |
| 链表 | ListNode(自定义) | 反转链表、环形链表、合并链表、LRU缓存 |
| 二叉树 | TreeNode(自定义) | 中序遍历、最大深度、对称二叉树、最近公共祖先 |
| 前缀树 | TrieNode(自定义) | 实现 Trie(208) |
| 矩阵/二维数组 | int[][] | 矩阵置零、螺旋矩阵、旋转图像、搜索二维矩阵 |
| 图(邻接表) | List |
课程表(拓扑排序) |
按算法思想分类
| 模块 | 核心思想 | 代表题目 |
|---|---|---|
| 双指针 | 同向/相向指针遍历 | 移动零、盛最多水、三数之和、接雨水 |
| 滑动窗口 | 双指针维护动态区间 | 无重复字符最长子串、字母异位词、最小覆盖子串 |
| 二分查找 | 不断缩小搜索区间 | 搜索插入位置、旋转数组、两数组的中位数 |
| 回溯 | 选择-探索-撤销(DFS+剪枝) | 子集、全排列、N皇后、单词搜索 |
| 贪心 | 每一步局部最优 → 全局最优 | 划分字母区间 |
| 动态规划 | 重叠子问题 + 状态转移 | 爬楼梯、打家劫舍、零钱兑换、最长递增子序列 |
| 多维DP | 二维及以上状态表 | 不同路径、最长公共子序列、编辑距离 |
| 图论 | DFS/BFS / 拓扑排序 / 并查集 | 岛屿数量、腐烂的橘子、课程表 |
| 特殊技巧 | 数学性质 / 位运算 / 链表判圈 | 只出现一次的数字、多数元素、颜色分类、寻找重复数 |
三、时间复杂度与空间复杂度全景对比
下表是对 11 大模块中 每一类核心操作 的时间与空间复杂度的全景汇总。
3.1 数据结构操作复杂度
| 数据结构 | 核心操作 | 时间复杂度 | 空间复杂度 | 备注 |
|---|---|---|---|---|
| 哈希表 | 查找 / 插入 / 删除 | O(1) 平均 | O(n) | 最坏 O(n) 哈希碰撞 |
| 栈 | 入栈 / 出栈 / 取栈顶 | O(1) | O(n) | 严格 O(1) 操作 |
| 堆(优先队列) | 插入(offer) | O(log n) | O(n) | 堆化操作 |
| 堆(优先队列) | 删除堆顶(poll) | O(log n) | O(n) | 下沉调整 |
| 堆(优先队列) | 取堆顶(peek) | O(1) | O(1) | — |
| 链表 | 查找/访问 | O(n) | O(n) | 不支持随机访问 |
| 链表 | 插入/删除(已知位置) | O(1) | O(1) | 需先遍历到目标 |
| 二叉树 | 遍历(DFS/BFS) | O(n) | O(h) | h 为树高 |
| 前缀树 | 插入 / 搜索 | O(L) | O(26×N×L) | L 为字符串长度 |
| 矩阵 | 遍历 | O(mn) | O(1) | 额外空间取决于算法 |
3.2 算法复杂度对比
| 算法模块 | 最佳时间复杂度 | 最差时间复杂度 | 空间复杂度 | 适用数据规模 |
|---|---|---|---|---|
| 暴力枚举 | O(n) | O(n!) | O(1) | n ≤ 20 |
| 双指针 | O(n) | O(n²)(三数之和) | O(1) | 很大 |
| 滑动窗口 | O(n) | O(n) | O(k) | 很大 |
| 二分查找 | O(log n) | O(log n) | O(1) | 极大 |
| 回溯 | O(n·2^n) ~ O(n!) | O(n!) ~ O(n·n!) | O(n) | n ≤ 15~20 |
| 贪心 | O(n) | O(n log n) | O(1) ~ O(n) | 很大 |
| 动态规划(一维) | O(n) | O(n²) | O(n) → O(1) 可优化 | n ≤ 10⁵ |
| 多维DP | O(mn) | O(n³) | O(mn) → O(n) 可优化 | 维度数决定 |
| 图论 DFS/BFS | O(V+E) | O(V+E) | O(V) | 中等 |
| 图论 拓扑排序 | O(V+E) | O(V+E) | O(V+E) | 中等 |
| 图论 并查集 | O(α(n)) | O(α(n)) | O(n) | 极大(α为反阿克曼函数) |
3.3 LeetCode 热门 100 题中各模块时间复杂度速查
| 模块 | 代表题 | 最优解法 | 时间复杂度 | 空间复杂度 |
|---|---|---|---|---|
| 哈希表 | 两数之和 | 哈希表 | O(n) | O(n) |
| 哈希表 | 最长连续序列 | HashSet + 起点延伸 | O(n) | O(n) |
| 双指针 | 盛最多水的容器 | 左右指针(相向) | O(n) | O(1) |
| 双指针 | 三数之和 | 排序 + 双指针 | O(n²) | O(1) |
| 双指针 | 接雨水 | 左右指针(维护最高) | O(n) | O(1) |
| 滑动窗口 | 无重复最长子串 | 哈希集合 + 窗口 | O(n) | O(k) |
| 滑动窗口 | 最小覆盖子串 | 频次计数 + 窗口 | O(n+m) | O(k) |
| 二分查找 | 搜索旋转数组 | 二分 + 有序区间判定 | O(log n) | O(1) |
| 二分查找 | 两数组中位数 | 二分较短的数组 | O(log min(m,n)) | O(1) |
| 回溯 | 子集 | start 控制递归 |
O(n·2^n) | O(n) |
| 回溯 | N 皇后 | 列+对角线剪枝 | O(n!) | O(n²) |
| 贪心 | 划分字母区间 | 最后位置 + 边界切分 | O(n) | O(1) |
| 动态规划 | 爬楼梯 | 一维 DP | O(n) | O(1) |
| 动态规划 | 零钱兑换 | 完全背包 DP | O(amount·n) | O(amount) |
| 动态规划 | 最长递增子序列 | DP + 二分优化 | O(n log n) | O(n) |
| 多维DP | 不同路径 | 二维DP / 滚动数组 | O(mn) | O(n) |
| 多维DP | 编辑距离 | 二维DP / 滚动数组 | O(mn) | O(n) |
| 栈 | 柱状图最大矩形 | 单调栈 + 哨兵 | O(n) | O(n) |
| 栈 | 字符串解码 | 双栈(数字+字符串) | O(n·maxK) | O(n) |
| 堆 | 第K大元素 | 小顶堆(大小k) | O(n log k) | O(k) |
| 堆 | 数据流中位数 | 双堆(大顶+小顶) | O(log n) 插入 | O(n) |
| 数组/技巧 | 最大子数组和 | Kadane 算法 | O(n) | O(1) |
| 数组/技巧 | 缺失第一个正数 | 原地哈希 | O(n) | O(1) |
| 矩阵 | 矩阵置零 | 第一行/列作标记 | O(mn) | O(1) |
| 矩阵 | 搜索二维矩阵 II | Z字形搜索 | O(m+n) | O(1) |
| 链表 | 环入口 | 快慢指针 | O(n) | O(1) |
| 链表 | 排序链表 | 归并排序(自底向上) | O(n log n) | O(1) |
| 图论 | 岛屿数量 | DFS/BFS 染色 | O(mn) | O(mn) |
| 图论 | 课程表 | 拓扑排序(Kahn) | O(V+E) | O(V+E) |
四、算法选择心法:遇到新题怎么想?
4.1 问题特征 → 算法映射
当你在面试或刷题中遇到一个新问题时,可以按照以下思路快速定位解法:
输入特征 → 优先考虑的算法
──────────────────────────────────────────────────
数据规模 n ≤ 20 → 回溯 / 状态压缩
数据规模 n ≤ 1000 → O(n²) 可接受(DP、暴力)
数据规模 n ≤ 10⁵ → O(n log n)(排序、二分、堆)
数据规模 n ≤ 10⁶+ → O(n) 或 O(1)(哈希、贪心、双指针)
需找"最长/最短子串" → 滑动窗口
需找"子数组和=target" → 前缀和 + 哈希
需找"第K大/小" → 堆 / 快速选择
有序数组 / 部分有序 → 二分查找
需枚举所有排列/组合/子集 → 回溯
需找最值,且子问题重叠 → 动态规划
每步局部最优 → 全局最优 → 贪心(需证明)
图/树/网格连通性 → DFS / BFS
依赖关系 / 课程安排 → 拓扑排序
成对元素 / 匹配 → 栈 / 哈希表
原地操作 / O(1)空间 → 双指针 / 原地哈希
4.2 复杂度渐进关系速记
O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(2ⁿ) < O(n!)
10⁶ → O(n) 或 O(n log n) ✅ 可行
10⁴ → O(n²) ✅ 可行
10² → O(n³) ⚠️ 勉强
20 → O(2ⁿ) / O(n!) ⚠️ 剪枝后可过
五、各模块核心心法速记
哈希表
“用空间记录历史,避免未来重复查找。” 核心能力:O(1) 的存在性查询。适合求和、配对、去重、计数、归类。
双指针
“一次遍历代替嵌套循环,O(1) 空间优化 O(n²) 时间。” 核心能力:同向(快慢)用于原地修改,相向(左右)用于有序数组配对和最值。
滑动窗口
“右指针扩张找可行解,左指针收缩找最优解。” 核心能力:子串/子数组问题的 O(n) 利器,配合频次计数器。
二分查找
“不断缩小搜索区间,排除不可能的一半。” 核心能力:O(log n) 在有序或部分有序空间中精确定位。
回溯
“选择 → 递归 → 撤销。暴力穷举 + 剪枝。” 核心能力:排列、组合、子集、分割、棋盘问题的通用模板。
贪心
“每步局部最优,累积出全局最优。” 核心能力:需要证明贪心选择性质,常用于区间、调度、边界类问题。
动态规划
“定义状态 → 转移方程 → 初始化 → 填表顺序 → 返回结果。” 核心能力:多阶段决策最优解,用空间换时间避免重复计算。
栈
“LIFO 保存等待处理的状态。匹配、回溯、单调栈三大场景。” 核心能力:括号匹配、嵌套解码、下一个更大元素、最大矩形面积。
堆
“动态极值容器。小顶堆保留 TopK,大顶堆保留 BottomK。” 核心能力:O(log n) 插入 + O(1) 获取极值,适合数据流和 TopK。
链表
“指针操作的艺术。虚拟头结点 + 双指针 + 递归。” 核心能力:反转、合并、环检测、随机复制、归并排序。
矩阵
“将二维操作转化为一维或常量操作。” 核心能力:原地标记、边界收缩、转置+翻转、单调性搜索。
图论
“状态传播(DFS/BFS)、依赖顺序(拓扑排序)、字符串查找(Trie)。” 核心能力:连通性检测、层数传播、环检测、前缀匹配。
六、学习路线建议
第一阶段:基础数据结构(1~2 周)
- 数组与字符串:双指针、滑动窗口、前缀和
- 链表:反转、合并、快慢指针、环检测
- 栈与队列:括号匹配、单调栈、最小栈
第二阶段:核心算法思想(2~3 周)
- 哈希表:两数之和系列、分组、连续序列
- 二叉树:遍历框架、递归分解、BST、路径和
- 堆:TopK、前K高频、中位数
- 二分查找:边界查找、旋转数组、双数组
第三阶段:进阶算法(3~4 周)
- 回溯:子集、组合、排列、分割、N皇后
- 动态规划(一维):线性DP、背包DP、子序列DP
- 多维DP:网格路径、双序列匹配、编辑距离
- 图论:DFS/BFS、拓扑排序、Trie
第四阶段:综合与技巧(持续)
- 矩阵专题:原地标记、螺旋遍历、旋转
- 贪心与技巧:摩尔投票、荷兰国旗、Floyd判圈
- 混合应用:前缀树+回溯(单词搜索 II)、堆+分治(395题)
七、写在最后
算法学习没有捷径,但有方法论。LeetCode 热门 100 题之所以"热门",正是因为它们覆盖了面试中最常考的算法模型和数据结构。吃透这 100 道题,意味着你掌握了:
- 11 种算法思想(枚举、双指针、滑动窗口、二分、回溯、贪心、DP、分治、拓扑、并查集、位运算)
- 8 种数据结构(数组、链表、栈、队列、哈希表、树、堆、图)
- 3 种优化思路(空间换时间、状态复用、单调性剔除)
“刷题不在多,在于精。精在于总结,在于归纳,在于形成条件反射。”
当你看到"连续子数组"想到前缀和,看到"子串"想到滑动窗口,看到"第K大"想到堆,看到"所有可能"想到回溯,看到"最值"想到 DP — 你就完成了从"刷题"到"解题"的蜕变。
祝你在 Java 后端开发与算法面试的道路上越走越远!🚀