算法解题框架与 LeetCode 刷题清单
题目来源:labuladong 算法笔记官方习题章节。本文记录整理时的 26 个专题、171 道主习题;官网调整后数量可能变化。标记说明:📋 = 官网习题章节收录,⭐ = 官网文章引用或推荐补充。
速成学习路线(来自官网)
第0步:先刷二叉树(建立递归思维) → 第1章:基本技巧 → 第2章:二叉树进阶 → 第3章:动态规划 → 第4章:其他算法
怎样把清单变成能力
清单解决“练什么”,不能证明“已经掌握”。每个专题按下面的闭环推进:
- 先选一道代表题,不看答案写出输入、输出、约束和最小反例。
- 用一句话定义状态或指针含义,再写代码;不能解释变量含义时,模板还没有真正掌握。
- 用示例、边界和随机小数据验证,并记录时间、空间复杂度。
- 隔 1 天和 1 周各重写一次;第二次仍需要背完整代码时,回到框架与不变量。
| 记录项 | 示例 |
|---|---|
| 题目与日期 | 209. 长度最小的子数组,2026-09-06 |
| 识别信号 | 连续子数组、元素非负、窗口和达到阈值 |
| 不变量 | 收缩前窗口满足条件;收缩后继续寻找更短答案 |
| 失败用例 | 空数组、单元素、目标不可达、答案在数组末尾 |
| 复杂度 | 时间 O(n),空间 O(1) |
| 复习结果 | 次日独立完成;一周后边界条件出错 |
可先读 数据结构 建立术语,再用 算法套路与解题框架 理解模板来源,最后在本页选题验证。
第一章:基本技巧
1.1 链表双指针
📋 官网习题章节:链表双指针经典习题
核心框架
虚拟头结点 → 简化边界处理
快慢指针(速度差)→ 中点、环检测
前后指针(步数差)→ 倒数第K个
双指针分别构建 → 链表分解
优先级队列 → K路合并
官网习题(6道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 82 | 删除排序链表中的重复元素 II | 链表分解(双指针分别构建) |
| 378 | 有序矩阵中第 K 小的元素 | 优先级队列 / 二分 |
| 373 | 查找和最小的 K 对数字 | 优先级队列 |
| 2 | 两数相加 | 同步双指针 + 进位 |
| 445 | 两数相加 II | 栈辅助 / 反转链表 |
| 287 | 寻找重复数 | 快慢指针(等价环形链表II) |
⭐ 文章中引用:83(删除排序链表中的重复元素)、23(合并K个升序链表)、142(环形链表 II)
1.2 数组双指针
📋 官网习题章节:数组双指针经典习题
核心框架
快慢指针(同向) → 原地去重、删除元素、移动零
左右指针(相向) → 两数之和II、反转数组
矩阵遍历技巧 → 转置、对角线、旋转
官网习题(9道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 80 | 删除有序数组中的重复项 II | 快慢指针变体 |
| 125 | 验证回文串 | 左右指针 |
| 75 | 颜色分类 | 三指针(荷兰国旗) |
| 88 | 合并两个有序数组 | 逆向双指针 |
| 977 | 有序数组的平方 | 左右指针 |
| 1329 | 将矩阵按对角线排序 | 矩阵对角线遍历 |
| 1260 | 二维网格迁移 | 一维化索引 |
| 867 | 转置矩阵 | 矩阵操作 |
| 14 | 最长公共前缀 | 纵向扫描 |
⭐ 文章中引用:26(删除有序数组中的重复项)、27(移除元素)、283(移动零)、21(合并两个有序链表)、151(颠倒字符串中的单词)
1.3 滑动窗口
📋 官网习题章节:滑动窗口算法经典习题
核心框架
int left = 0, right = 0;
while (right < nums.length) {
// 扩大窗口,加入 nums[right]
right++;
while (需要收缩) {
// 缩小窗口,移除 nums[left]
left++;
}
// 更新答案
}
官网习题(7道)
| # | 题目 | 特征 |
|---|---|---|
| 1658 | 将 x 减到 0 的最小操作数 | 逆向思维:找最长子数组和为 sum-x |
| 1004 | 最大连续1的个数 III | 条件窗口(最多K个0) |
| 424 | 替换后的最长重复字符 | 窗口内最多K个不同字符 |
| 219 | 存在重复元素 II | 固定窗口 + HashSet |
| 220 | 存在重复元素 III | 桶排序 / TreeSet |
| 209 | 长度最小的子数组 | 收缩条件:sum >= target |
| 395 | 至少有 K 个重复字符的最长子串 | 分治 + 滑动窗口 |
⭐ 文章中引用:713(乘积小于K的子数组)、560(和为K的子数组)、1425(带限制的子序列和)、862(和至少为K的最短子数组)、53(最大子数组和)
1.4 二分搜索
📋 官网习题章节:二分搜索算法经典习题
核心框架
基础框架:两端都闭 [left, right],while (left <= right)
左侧边界:mid == target → right = mid - 1,返回 left
右侧边界:mid == target → left = mid + 1,返回 right
泛化运用:f(x) 单调 + 求边界值 → 二分搜索
官网习题(11道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 566 | 重塑矩阵 | 一维化索引 |
| 74 | 搜索二维矩阵 | 二维 → 一维二分 |
| 240 | 搜索二维矩阵 II | 右上角开始搜索 / 二分 |
| 392 | 判断子序列 | 双指针 / 二分预处理 |
| 658 | 找到 K 个最接近的元素 | 二分 + 双指针扩展 |
| 35 | 搜索插入位置 | 左侧边界变体 |
| 162 | 寻找峰值 | 二分爬坡法 |
| 852 | 山脉数组的峰顶索引 | 二分找最大值 |
| 33 | 搜索旋转排序数组 | 二分 + 分段判断 |
| 81 | 搜索旋转排序数组 II | 含重复元素处理 |
| 153 | 寻找旋转排序数组中的最小值 | 二分旋转点 |
⭐ 文章中引用:792(匹配子序列的单词数)、5(最长回文子串)
1.5 栈
📋 官网习题章节:栈的经典习题
官网习题(9道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 71 | 简化路径 | 栈处理路径 |
| 143 | 重排链表 | 栈辅助(后进先出) |
| 20 | 有效的括号 | 栈匹配括号 |
| 150 | 逆波兰表达式求值 | 栈计算 |
| 225 | 用队列实现栈 | 数据结构设计 |
| 388 | 文件的最长绝对路径 | 栈记录层级 |
| 394 | 字符串解码 | 栈 + 递归 |
| 155 | 最小栈 | 辅助栈存最小值 |
| 895 | 最大频率栈 | 频率Map + 栈Map |
⭐ 文章中引用:239(滑动窗口最大值)
1.6 队列
📋 官网习题章节:队列的经典习题
官网习题(5道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 933 | 最近的请求次数 | 队列维护时间窗口 |
| 622 | 设计循环队列 | 数组实现循环队列 |
| 641 | 设计循环双端队列 | 双向操作 |
| 1670 | 设计前中后队列 | 双端队列设计 |
| 2073 | 买票需要的时间 | 队列模拟 |
⭐ 文章中引用:346(数据流中的移动平均值)
1.7 单调栈
📋 官网习题章节:单调栈的几种变体及经典习题
核心框架
单调栈模板:倒序遍历 + while 弹出较小元素
while (!stack.isEmpty() && stack.peek() <= nums[i]) stack.pop();
res[i] = stack.isEmpty() ? 0 : stack.peek();
stack.push(nums[i]);
适用场景:下一个更大/更小元素、柱状图最大矩形
官网习题(8道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 1019 | 链表中的下一个更大节点 | 单调栈 + 链表 |
| 1944 | 队列中可以看到的人数 | 单调栈(递减栈) |
| 1475 | 商品折扣后的最终价格 | 单调栈(正序遍历) |
| 901 | 股票价格跨度 | 单调栈(存跨度) |
| 402 | 移掉 K 位数字 | 单调栈 + 贪心 |
| 853 | 车队 | 到达时间 + 单调栈 |
| 581 | 最短无序连续子数组 | 单调栈找左右边界 |
| 84 | 柱状图中最大的矩形 | 单调栈经典题 |
第二章:二叉树
二叉树思维模式
遍历思维(traverse):无返回值 + 外部变量
前序位置:刚进入节点 → 自上而下传参
中序位置:左子树处理完 → BST有序
后序位置:即将离开节点 → 可获得子树信息(能力最强)
分解问题思维(f(root) 有返回值):
定义递归函数 → 子树答案推导 → 后序位置写逻辑
层序遍历:BFS + Queue + for (int i = 0; i < sz; i++) 按层处理
2.1 用「遍历」思维解题 I
📋 官网习题章节:用「遍历」思维解题 I
官网习题(6道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 257 | 二叉树的所有路径 | 前序遍历 + 回溯 |
| 129 | 求根节点到叶节点数字之和 | 前序遍历传参 |
| 199 | 二叉树的右视图 | DFS记录每层第一个 |
| 988 | 从叶结点开始的最小字符串 | 前序遍历 + 回溯比较 |
| 1022 | 从根到叶的二进制数之和 | 前序遍历传参 |
| 1457 | 二叉树中的伪回文路径 | 前序遍历 + 位运算 |
2.2 用「遍历」思维解题 II
📋 官网习题章节:用「遍历」思维解题 II
官网习题(7道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 404 | 左叶子之和 | 遍历 + 条件判断 |
| 623 | 在二叉树中增加一行 | 遍历 + 层数判断 |
| 971 | 翻转二叉树以匹配先序遍历 | 遍历 + 贪心翻转 |
| 987 | 二叉树的垂序遍历 | 遍历 + 坐标排序 |
| 993 | 二叉树的堂兄弟节点 | 遍历记录父节点和深度 |
| 1315 | 祖父节点值为偶数的节点和 | 遍历传参爷爷值 |
| 1448 | 统计二叉树中好节点的数目 | 遍历传参路径最大值 |
2.3 用「分解问题」思维解题 I
📋 官网习题章节:用「分解问题」思维解题 I
官网习题(7道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 105 | 从前序与中序遍历序列构造二叉树 | 找根 + 递归构建左右子树 |
| 106 | 从中序与后序遍历序列构造二叉树 | 找根 + 递归构建左右子树 |
| 889 | 根据前序和后序遍历构造二叉树 | 左子树根确定分界 |
| 331 | 验证二叉树的前序序列化 | 节点和空位的关系 |
| 894 | 所有可能的真二叉树 | 枚举左子树 + 右子树组合 |
| 998 | 最大二叉树 II | 插入节点保持最大树 |
| 1110 | 删点成林 | 后序分解 + 处理删除 |
⭐ 文章中引用:654(最大二叉树)
2.4 用「分解问题」思维解题 II
📋 官网习题章节:用「分解问题」思维解题 II
官网习题(4道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 100 | 相同的树 | 分解:左右都相同 |
| 101 | 对称二叉树 | 分解:左的左 = 右的右 |
| 951 | 翻转等价二叉树 | 分解:两种情况之一成立 |
| 124 | 二叉树中的最大路径和 | 后序分解(单边 vs 双边) |
⭐ 文章中引用:543(二叉树的直径)、366(寻找二叉树的叶子节点)
2.5 运用层序遍历解题 I
📋 官网习题章节:运用层序遍历解题 I
官网习题(11道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 102 | 二叉树的层序遍历 | BFS 队列模板 |
| 107 | 二叉树的层序遍历 II | 层序遍历 + 结果反转 |
| 103 | 二叉树的锯齿形层序遍历 | BFS + 方向标记 |
| 117 | 填充每个节点的下一个右侧节点指针 II | BFS 连接同层节点 |
| 662 | 二叉树最大宽度 | BFS + 节点编号 |
| 515 | 在每个树行中找最大值 | BFS 每层统计 |
| 637 | 二叉树的层平均值 | BFS 每层统计 |
| 958 | 二叉树的完全性检验 | BFS + 空节点标记 |
| 1161 | 最大层内元素和 | BFS 每层求和 |
| 1302 | 层数最深叶子节点的和 | BFS 求最后一层和 |
| 1609 | 奇偶树 | BFS + 层条件判断 |
⭐ 文章中引用:116(填充每个节点的下一个右侧节点指针)、1104(二叉树寻路)、199(二叉树的右视图)
2.6 运用层序遍历解题 II
📋 官网习题章节:运用层序遍历解题 II
官网习题(3道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 919 | 完全二叉树插入器 | 队列维护插入位置 |
| 872 | 叶子相似的树 | 层序遍历收集叶节点 |
| 863 | 二叉树中所有距离为 K 的结点 | BFS + 父节点映射 |
第三章:动态规划
DP 核心框架
三步法:
1. 明确状态(会变化的变量有哪些)
2. 明确选择(导致状态变化的行为)
3. 定义 dp 数组/函数
自顶向下:递归 + 备忘录
自底向上:迭代 + DP table
子序列问题 → dp[i] = 以 i 结尾的结果
双字符串 → dp[i][j] = s1[0..i] 和 s2[0..j] 的关系
3.1 动态规划经典习题 I
📋 官网习题章节:动态规划经典习题 I
官网习题(6道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 343 | 整数拆分 | dp[n] = max(j × (n-j), j × dp[n-j]) |
| 63 | 不同路径 II | 网格DP + 障碍物处理 |
| 1262 | 可被三整除的最大和 | DP + 余数状态 |
| 120 | 三角形最小路径和 | 自底向上 DP |
| 368 | 最大整除子集 | DP + 记录前驱 |
| 718 | 最长重复子数组 | dp[i][j] 双序列 DP |
3.2 动态规划经典习题 II
📋 官网习题章节:动态规划经典习题 II
官网习题(5道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 97 | 交错字符串 | 双序列 DP |
| 152 | 乘积最大子数组 | 同时维护 min 和 max |
| 221 | 最大正方形 | dp[i][j] = min(上,左,左上) + 1 |
| 329 | 矩阵中的最长递增路径 | 记忆化搜索(DFS + 备忘录) |
| 1235 | 规划兼职工作 | 按结束时间排序 + DP + 二分 |
⭐ 文章中引用:21(合并两个有序链表)、53(最大子数组和)
3.3 背包问题经典习题
📋 官网习题章节:背包问题经典习题
核心框架
0-1背包(每个物品选或不选):
二维:dp[i][w] = max(dp[i-1][w], dp[i-1][w-wt[i]] + val[i])
一维优化:for w = W..0(逆向遍历,保证不重复)
完全背包(每个物品可选无限次):
一维:for w = 0..W(正向遍历,允许重复选)
子集背包(能否装满):
dp[i][w] = dp[i-1][w] || dp[i-1][w-nums[i]](布尔DP)
官网习题(3道)
| # | 题目 | 类型 |
|---|---|---|
| 1049 | 最后一块石头的重量 II | 0-1背包(子集背包变体) |
| 474 | 一和零 | 二维费用的0-1背包 |
| 3180 | 执行操作可获得的最大总奖励 I | 0-1背包变体 |
第四章:其他经典算法
4.1 回溯算法经典习题 I
📋 官网习题章节:回溯算法经典习题 I
核心框架
result = []
void backtrack(路径, 选择列表):
if 满足结束条件: result.add(路径); return
for 选择 in 选择列表:
做选择 → backtrack → 撤销选择
子集/组合 → 用 start(防止回头)
排列 → 用 used[](标记已选)
有重复元素 → 先排序 + 同层剪枝
官网习题(10道)
| # | 题目 | 特征 |
|---|---|---|
| 967 | 连续差相同的数字 | 回溯构造数字 |
| 980 | 不同路径 III | 回溯遍历所有路径 |
| 526 | 优美的排列 | 回溯 + 约束 |
| 491 | 非递减子序列 | 回溯 + 同层去重 |
| 131 | 分割回文串 | 回溯 + 预处理 |
| 93 | 复原 IP 地址 | 回溯 + 剪枝 |
| 89 | 格雷编码 | 回溯 / 公式法 |
| 17 | 电话号码的字母组合 | 回溯组合 |
| 79 | 单词搜索 | 二维回溯 |
| 473 | 火柴拼正方形 | 回溯 + 剪枝(桶视角) |
⭐ 文章中引用:40(组合总和 II)
4.2 回溯算法经典习题 II
📋 官网习题章节:回溯算法经典习题 II
官网习题(7道)
| # | 题目 | 特征 |
|---|---|---|
| 1219 | 黄金矿工 | 二维回溯 + 最大值 |
| 1849 | 将字符串拆分为递减的连续值 | 回溯 + 数值比较 |
| 1593 | 拆分字符串使唯一子字符串数目最大 | 回溯 + 去重 |
| 1079 | 活字印刷 | 回溯排列(含重复) |
| 996 | 平方数组的数目 | 回溯排列 + 约束 |
| 784 | 字母大小写全排列 | 回溯 + 大小写变换 |
| 638 | 大礼包 | 回溯 + DP |
4.3 回溯算法经典习题 III
📋 官网习题章节:回溯算法经典习题 III
官网习题(4道)
| # | 题目 | 特征 |
|---|---|---|
| 301 | 删除无效的括号 | 回溯 + 最少删除 |
| 2850 | 将石头分散到网格图的最少移动次数 | 回溯 + 全排列匹配 |
| 1723 | 完成所有工作的最短时间 | 回溯 + 任务分配 |
| 2305 | 公平分发饼干 | 回溯 + 桶分配 |
⭐ 文章中引用:1011(在D天内送达包裹的能力)
4.4 BFS 经典习题 I
📋 官网习题章节:BFS 经典习题 I
核心框架
int bfs(start, target) {
Queue q; q.offer(start); visited.add(start);
int step = 0;
while (!q.isEmpty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
cur = q.poll();
if (cur == target) return step;
for (neighbor : cur.neighbors)
if (!visited.contains(n)) { q.offer(n); visited.add(n); }
}
step++;
}
}
官网习题(10道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 919 | 完全二叉树插入器 | BFS 维护插入位置 |
| 117 | 填充每个节点的下一个右侧节点指针 II | BFS 连接同层节点 |
| 662 | 二叉树最大宽度 | BFS + 节点编号 |
| 863 | 二叉树中所有距离为 K 的结点 | BFS + 父节点映射 |
| 310 | 最小高度树 | BFS 拓扑排序(剥洋葱) |
| 841 | 钥匙和房间 | BFS / DFS 连通性 |
| 1306 | 跳跃游戏 III | BFS 跳跃搜索 |
| 433 | 最小基因变化 | BFS + 字符变换 |
| 1926 | 迷宫中离入口最近的出口 | 矩阵 BFS |
| 1091 | 二进制矩阵中的最短路径 | 矩阵 BFS |
⭐ 文章中引用:102(二叉树的层序遍历)、116(填充每个节点的下一个右侧节点指针)、1104(二叉树寻路)、199(二叉树的右视图)、286(墙与门)
4.5 BFS 经典习题 II
📋 官网习题章节:BFS 经典习题 II
官网习题(10道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 994 | 腐烂的橘子 | 多源 BFS |
| 924 | 尽量减少恶意软件的传播 | BFS + 连通分量 |
| 2101 | 引爆最多的炸弹 | BFS 有向图传播 |
| 542 | 01 矩阵 | 多源 BFS |
| 417 | 太平洋大西洋水流问题 | DFS/BFS + 逆流 |
| 365 | 水壶问题 | BFS 状态搜索 / 数学 |
| 721 | 账户合并 | BFS/并查集合并连通分量 |
| 2850 | 将石头分散到网格图的最少移动次数 | BFS 最短路 |
| 127 | 单词接龙 | BFS + 双向BFS |
| 399 | 除法求值 | BFS 图搜索 |
⭐ 文章中引用:111(二叉树的最小深度)、1091(二进制矩阵中的最短路径)
4.6 Dijkstra 算法经典习题
📋 官网习题章节:Dijkstra 算法经典习题
核心框架
// Dijkstra: 优先队列 + distTo数组 + 松弛操作
PriorityQueue<State> pq; // 按distFromStart排序
int[] distTo = new int[n]; Arrays.fill(distTo, INF);
distTo[start] = 0; pq.offer(new State(start, 0));
while (!pq.isEmpty()) {
State cur = pq.poll();
if (cur.distFromStart > distTo[cur.id]) continue; // 跳过旧数据
for (neighbor : neighbors) {
int newDist = distTo[cur.id] + weight;
if (newDist < distTo[neighbor]) {
distTo[neighbor] = newDist;
pq.offer(new State(neighbor, newDist));
}
}
}
官网习题(5道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 743 | 网络延迟时间 | Dijkstra 模板题 |
| 1631 | 最小体力消耗路径 | Dijkstra 变体(最小化路径最大值) |
| 1514 | 概率最大的路径 | Dijkstra 变体(最大化路径积) |
| 1368 | 使网格图至少有一条有效路径的最小代价 | Dijkstra + 0-1 BFS |
| 787 | K 站中转内最便宜的航班 | Dijkstra + 中转次数限制 |
4.7 并查集(Union-Find)经典习题
📋 官网习题章节:并查集经典习题
核心框架
class UF {
int[] parent; int count;
int find(int x) { // 路径压缩
if (parent[x] != x) parent[x] = find(parent[x]);
return parent[x];
}
void union(int p, int q) {
int rootP = find(p), rootQ = find(q);
if (rootP == rootQ) return;
parent[rootQ] = rootP; count--;
}
}
官网习题(3道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 547 | 省份数量 | 并查集模板题 |
| 1361 | 验证二叉树 | 并查集检查连通性 |
| 947 | 移除最多的同行或同列石头 | 并查集合并行和列 |
⭐ 文章中引用:261(以图判树)
4.8 线段树经典习题
📋 官网习题章节:线段树经典习题
官网习题(4道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 729 | 我的日程安排表 I | 线段树 / TreeSet 区间 |
| 731 | 我的日程安排表 II | 线段树 + 双重预订 |
| 732 | 我的日程安排表 III | 线段树 + 最大预订次数 |
| 699 | 掉落的方块 | 线段树(区间更新+最大值查询) |
4.9 Trie 树算法习题
📋 官网习题章节:Trie 树算法习题
核心框架
class TrieNode {
TrieNode[] children = new TrieNode[26];
boolean isEnd = false;
}
class Trie {
void insert(String word) { /* 遍历字符,创建节点 */ }
boolean search(String word) { /* 精确匹配 */ }
boolean startsWith(String prefix) { /* 前缀匹配 */ }
}
官网习题(4道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 208 | 实现 Trie (前缀树) | Trie 模板题 |
| 648 | 单词替换 | Trie 找最短前缀 |
| 211 | 添加与搜索单词 - 数据结构设计 | Trie + 通配符 DFS |
| 677 | 键值映射 | Trie 节点存值 |
4.10 数据结构设计
📋 官网习题章节:更多经典设计习题
官网习题(7道)
| # | 题目 | 核心技巧 |
|---|---|---|
| 729 | 我的日程安排表 I | 有序集合 / 线段树 |
| 950 | 按递增顺序显示卡牌 | 队列模拟 |
| 1700 | 无法吃午餐的学生数量 | 队列 + 计数 |
| 155 | 最小栈 | 辅助栈存最小值 |
| 1670 | 设计前中后队列 | 双端队列设计 |
| 895 | 最大频率栈 | 频率Map + 栈Map |
| 284 | 窥视迭代器 | 缓存下一个元素 |
⭐ 文章中引用:239(滑动窗口最大值)、251(展开二维向量)
附录
一、排序算法速查表
| 算法 | 时间(平均) | 时间(最坏) | 空间 | 稳定 |
|---|---|---|---|---|
| 快速排序 | O(n log n) | O(n²) | O(log n) | ❌ |
| 归并排序 | O(n log n) | O(n log n) | O(n) | ✅ |
| 堆排序 | O(n log n) | O(n log n) | O(1) | ❌ |
| 插入排序 | O(n²) | O(n²) | O(1) | ✅ |
| 冒泡排序 | O(n²) | O(n²) | O(1) | ✅ |
| 选择排序 | O(n²) | O(n²) | O(1) | ❌ |
| 计数排序 | O(n+k) | O(n+k) | O(k) | ✅ |
| 基数排序 | O(nk) | O(nk) | O(n+k) | ✅ |
| 桶排序 | O(n+k) | O(n²) | O(n+k) | ✅ |
二、习题章节汇总
| 章节 | 专题 | 题目数 |
|---|---|---|
| 1.1 | 链表双指针 | 6 |
| 1.2 | 数组双指针 | 9 |
| 1.3 | 滑动窗口 | 7 |
| 1.4 | 二分搜索 | 11 |
| 1.5 | 栈 | 9 |
| 1.6 | 队列 | 5 |
| 1.7 | 单调栈 | 8 |
| 2.1~2.2 | 二叉树遍历思维 | 13 |
| 2.3~2.4 | 二叉树分解思维 | 11 |
| 2.5~2.6 | 二叉树层序遍历 | 14 |
| 3.1~3.2 | 动态规划 | 11 |
| 3.3 | 背包问题 | 3 |
| 4.1~4.3 | 回溯算法 | 21 |
| 4.4~4.5 | BFS 算法 | 20 |
| 4.6 | Dijkstra | 5 |
| 4.7 | 并查集 | 3 |
| 4.8 | 线段树 | 4 |
| 4.9 | Trie 树 | 4 |
| 4.10 | 数据结构设计 | 7 |
| 合计 | 26个专题 | 171 |
三、使用建议
- 按依赖选择顺序:递归不熟时先练二叉树;数组和链表基础薄弱时先回到基本技巧,不必机械遵循完整目录。
- 先写不变量再写模板:模板只是实现骨架,题目约束决定窗口何时收缩、状态如何转移、节点是否可重复访问。
- 一题多解用于比较边界:记录不同解法需要的前提、复杂度和失败用例,而不只是多抄一份代码。
- 限时服务于诊断:时间到了先标记卡在建模、边界还是编码,再查看提示;固定分钟数不是能力标准。
- 用间隔复习检验迁移:复习时更换输入或相邻题,确认能从特征推出框架,而不是记住题号。
四、专题完成标准
- 能说明这个框架解决什么问题,以及至少一个不适用场景。
- 能从空输入、最小输入、重复值、极值和无解情况中选择相关边界。
- 代码有可运行入口或在线判题记录,示例输出与预期一致。
- 能解释时间与空间复杂度来自哪一层循环、递归树或数据结构操作。
- 一周后能独立完成一道同类变体,并说出它与原题的关键差异。
本页是选题索引,不替代题目原文、约束和独立验证。题目编号、难度与官方专题可能调整,练习时以题目当前描述为准。
📋 = 官网习题章节收录(171道) ⭐ = 官网文章引用/推荐补充 🟢 简单 🟡 中等 🔴 困难