力扣算法解析按专题吃透,不做题海 速查 90 天路线 ⌂ 全部教程

附录模板速查、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!)
线性 DPO(n)O(n) 可压 O(1)70 / 198
二维 DP / LCSO(n·m)O(n·m)62 / 1143
01 / 完全背包O(n·V)O(V)416 / 322(V 为容量)
网格 DFS / BFSO(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 栈与队列「栈里存下标 + 新元素踢栈」骨架
层序遍历 BFS07 二叉树先取 size 再内层循环
回溯四件套08 递归与回溯path + 选择 + 撤销 + start/used 两个变体
DP 五步法09 DP 入门状态定义能说成人话
01 / 完全背包一维写法10 DP 进阶倒序 vs 正序,说清为什么
网格 DFS / 多源 BFS12 图论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~72DP 进阶: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 的核心你就拿下了。