附录模板速查、API 速查与 90 天路线
刷题时最常翻的三样东西集中在这里:复杂度对照表(判断思路能不能过)、 Java API 速查(不用背 API,会用就行)、全部模板的索引(默写级清单), 以及一条可以直接照着走的 90 天刷题路线。
A.1复杂度速查
各专题核心技巧的复杂度
| 技巧 | 时间 | 空间 | 代表题 |
|---|---|---|---|
| 哈希查找 | O(n) | O(n) | 1 两数之和 |
| 对撞双指针 | O(n) | O(1) | 11 盛最多水的容器 |
| 滑动窗口 | O(n) | O(k) | 3 无重复字符的最长子串 |
| 二分查找 | O(log n) | O(1) | 704 / 33 |
| 链表快慢指针 | O(n) | O(1) | 141 / 142 环形链表 |
| 单调栈 | O(n) | O(n) | 739 每日温度 |
| 二叉树递归 | O(n) | O(h) | 104 / 236(h 为树高) |
| 回溯 | O(指数级) | O(递归深度) | 46 全排列 O(n·n!) |
| 线性 DP | O(n) | O(n) 可压 O(1) | 70 / 198 |
| 二维 DP / LCS | O(n·m) | O(n·m) | 62 / 1143 |
| 01 / 完全背包 | O(n·V) | O(V) | 416 / 322(V 为容量) |
| 网格 DFS / BFS | O(n·m) | O(n·m) | 200 / 994 |
| 拓扑排序 | O(V+E) | O(V+E) | 207 课程表 |
配合总览 0.4 的数据范围表使用:先看 n 的范围定目标复杂度,再查这里哪个技巧能达成——
这就是大多数题的解题路径。
A.2Java 刷题 API 速查
数组与排序
int[] a = new int[n]; // 全零数组
int[] b = {3, 1, 2};
Arrays.sort(b); // 升序 O(n log n)
// 降序要给比较器(只能对 Integer[] 或 List 用)
Integer[] c = {3, 1, 2};
Arrays.sort(c, (x, y) -> y - x);
Arrays.fill(a, -1); // 整个数组填 -1(DP 初始化常用)
int[] d = Arrays.copyOfRange(b, 1, 3);// 截取 [1,3)
字符串
String s = "abc";
s.length(); s.charAt(0); // 长度 / 第 i 个字符
char[] cs = s.toCharArray(); // 转字符数组(要修改时)
String t = new String(cs);
StringBuilder sb = new StringBuilder();
sb.append('x'); sb.reverse(); sb.toString(); // 拼接/反转,O(1) 均摊
s.substring(1, 3); // 子串 [1,3)
String[] parts = "a,b".split(","); // 分割
s.trim(); s.equals(t); s.compareTo(t); // 去空白 / 比较(别用 ==)
Character.isLetterOrDigit(ch); Character.toLowerCase(ch);
集合三件套
Map<String, Integer> map = new HashMap<>();
map.put("a", 1); map.get("a");
map.getOrDefault("b", 0); // 计数场景标配:getOrDefault(key, 0) + 1
map.containsKey("a"); map.remove("a");
for (var e : map.entrySet()) e.getKey() + "=" + e.getValue();
map.keySet(); map.values();
Set<Integer> set = new HashSet<>();
set.add(1); set.contains(1); set.remove(1);
// 计数小技巧:merge 一行完成「存在则加,不存在则放」
map.merge(ch, 1, Integer::sum);
栈、队列、堆(Deque / Queue / PriorityQueue)
// 栈:用 Deque,别用遗留的 Stack 类
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1); stack.pop(); stack.peek(); // 压 / 弹 / 看顶
// 队列:Queue 接口
Queue<Integer> queue = new ArrayDeque<>();
queue.offer(1); queue.poll(); queue.peek(); // 入 / 出 / 看头
// 双端队列(滑窗、单调队列用)
Deque<Integer> dq = new ArrayDeque<>();
dq.offerLast(1); dq.pollLast(); dq.pollFirst(); dq.peekFirst();
// 堆:小顶堆默认;大顶堆给反向比较器
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
minHeap.offer(1); minHeap.poll(); minHeap.peek();
两个高频坑:
①
(a, b) -> b - a 这种相减写法在「极大值减极小值」时会整型溢出,
稳妥写法是 Integer.compare(a, b)(升序)或 Integer.compare(b, a)(降序);
② int[] 数组不能做 HashMap 的 key(比较的是引用不是内容),
需要时先包成 String 或 List<Integer>。
A.3全部模板索引
以下模板建议做到脱稿默写。点击跳到对应专题的完整讲解:
| 模板 | 所在专题 | 默写检验标准 |
|---|---|---|
| 对撞 / 快慢指针 | 01 双指针 | 能不假思索写出「while (l < r) 里移动哪个、为什么」 |
| 哈希计数 | 02 哈希表 | merge 一行计数、数组计数 int[26] |
| 滑动窗口 | 03 滑动窗口 | 右扩-收缩-更新三步顺序不乱,求最长/最短两种变体 |
| 二分(含左右边界) | 04 二分查找 | 闭区间模板 + 找第一个 ≥ target 的写法,不死循环 |
| 虚拟头节点 | 05 链表 | 知道什么时候必须用 dummy |
| 反转链表(迭代) | 05 链表 | prev/cur/next 三行核心,30 秒写完 |
| 单调栈 | 06 栈与队列 | 「栈里存下标 + 新元素踢栈」骨架 |
| 层序遍历 BFS | 07 二叉树 | 先取 size 再内层循环 |
| 回溯四件套 | 08 递归与回溯 | path + 选择 + 撤销 + start/used 两个变体 |
| DP 五步法 | 09 DP 入门 | 状态定义能说成人话 |
| 01 / 完全背包一维写法 | 10 DP 进阶 | 倒序 vs 正序,说清为什么 |
| 网格 DFS / 多源 BFS | 12 图论 | dirs 数组 + visited 时机 |
A.490 天刷题路线(Hot 100)
按本站专题排的 90 天计划(覆盖前 12 个基础专题;13~24 号进阶专题学完后按面试方向自选加练),每天 1 题、每周 6 题 + 1 天复盘,共约 75 题有效量。 「有效」的定义见总览 0.3 五步法。题目都来自力扣 Hot 100,标注了对应专题页:
| 阶段 | 天数 | 内容 |
|---|---|---|
| 第 1 周 | 1~6 | 数组与双指针:283 / 26 / 11 / 15 / 42 / 复盘 |
| 第 2 周 | 7~12 | 哈希表:1 / 242 / 49 / 128 / 560 / 复盘 |
| 第 3~4 周 | 13~24 | 滑动窗口(209 / 3 / 438 / 76)+ 二分(704 / 35 / 34 / 33 / 153 / 4) |
| 第 5 周 | 25~30 | 链表:203 / 206 / 21 / 141+142 / 19 / 复盘 |
| 第 6 周 | 31~36 | 栈与队列:20 / 155 / 232 / 739 / 394 / 复盘 |
| 第 7~8 周 | 37~48 | 二叉树:104 / 226 / 101 / 102 / 236 / 98 / 230 / 105 / 124 / 543 / 复盘 ×2 |
| 第 9~10 周 | 49~60 | 回溯:77 / 78 / 46 / 39 / 22 / 51 / 复盘 + DP 入门:70 / 746 / 198 / 62 / 复盘 |
| 第 11~12 周 | 61~72 | DP 进阶:300 / 1143 / 416 / 322 / 152 / 复盘 + 贪心:121 / 55 / 45 / 435 / 复盘 |
| 第 13 周 | 73~78 | 图论:200 / 994 / 207 / 210 / 复盘 ×2 |
| 缓冲 | 79~90 | 薄弱专题回炉:把之前「看了一眼题解才写出」的题全部脱稿重写一遍 |
这是校招备战型路线。如果你在备蓝桥杯 / 天梯赛,把第 11~13 周换成
更多 DP 与图论题;如果目标是实习面试,第 1~8 周的高频专题优先级最高。
A.5卡住了怎么办:看题解的正确姿势
卡住是常态,看题解不可耻。可耻的是看完就过。按下面这个阶梯来,把每次「看题解」的价值榨干:
| 阶梯 | 动作 | 什么时候升级到下一阶 |
|---|---|---|
| 1 | 只看本站该题的思路推导部分,到「想到这个解法」为止,不看代码,合上自己写 | 15 分钟还是写不出 |
| 2 | 看代码的前几行(状态定义 / 变量命名),推断后续,再自己写完 | 10 分钟还是写不出 |
| 3 | 看完整参考代码,逐行理解后合上,从头默写 | 默写通过所有用例 |
| 4 | 三天后脱稿重写(五步法第 5 步);写不出回到阶梯 3 | 一次通过 → 这题真正属于你了 |
标记你的「真不会」名单。凡是走到过阶梯 3 的题,记下来。
它们是你最宝贵的复习材料——面试前只复习这个名单,效率远高于盲目二刷。
Q. 阶梯 3 的「默写」和死记硬背有什么区别?
检验方法是:默写时你能说出每一行在整条思路里的位置(「这行是在做滑动窗口的收缩」)。 如果只是手指记忆,三天后重写必挂,那就回到思路推导重新理解。宁可慢,不要背。
用这份附录验收你的备考:复杂度表能对着数据范围口算出「这题目标复杂度是多少、用哪个技巧」;
模板索引里 12 个模板全部脱稿默写通过;90 天路线你能说出自己当前在第几周、落后多少。
三条都做到,Hot 100 的核心你就拿下了。