一般流程
基础知识 ⭐ 入门 🔥 高频
💡 核心要点
第一遍刷题最怕的不是不会,而是不知道该怎么下手。真正有效的一刷,不是直接看答案,而是按固定顺序把题目拆开:读题、暴力解、目标复杂度、实现、复盘。
概念
- 一刷题的目标不是“把题做掉”,而是建立判断框架。
- 第一遍不会很正常,但你必须知道自己卡在了读题、建模、实现还是复杂度判断。
- 只要第一次流程稳定,后面二刷、复盘和迁移都会轻松很多。
怎么处理
一刷题的固定顺序
- 先完整读题,明确输入、输出、限制条件和边界。
- 先写出最直接的暴力解,不要一开始就强求最优。
- 再问自己目标复杂度是多少,能不能从暴力解继续优化。
- 实现时先用 Java 或 C++ 写出最稳的版本,再考虑压缩写法。
- 做完后记录:这题属于哪一类,我最开始卡在了哪里。
做不出来时怎么办
- 先确认自己有没有把样例手推清楚。
- 再确认自己是不会建模,还是不会写代码。
- 最后再去看题解,而且只先看思路,不要先抄代码。
典型实例
| 阶段 | 你应该做什么 | 目标 |
|---|---|---|
| 读题阶段 | 画输入输出关系,补充边界样例 | 读懂题 |
| 暴力阶段 | 写最直接的思路 | 建立问题感觉 |
| 优化阶段 | 看能否降到 、 | 建立复杂度意识 |
| 复盘阶段 | 记录题型、触发信号、易错点 | 建立迁移能力 |
走题示例:以 LC 3 为例
上面是原则,这里是原则的具体演示。拿一道中等题“无重复字符的最长子串”走一遍五个阶段:
阶段 1:读题与准确化
- 输入:字符串
s,长度 0–10⁵ - 输出:无重复字符子串的最大长度(返回 int)
- 边界样例:空串 → 0;全重复
"aaa"→ 1;全不重复"abc"→ 3 - 隐含限制:子串是连续的(不是子序列)、字符集 ASCII 可能含空格/符号
阶段 2:暴力解
- 枚举所有子串
[i, j],检查是否无重复,取最大长度 - 复杂度: 枚举 + 检查,n=10⁵ 下 10¹⁵ 操作→超时是肯定的,但它是正确的。在面试中先说这个能充当安全网。
阶段 3:定复杂度上限 + 识别信号
- n=10⁵ → 需要 或
- 信号:连续子串 + 状态可增量维护(加入一个字符、移出一个字符都是 O(1))→ 滑动窗口
- 窗口状态:哈希集/频率数组 记录窗口内字符是否出现
- 求最长 → 不合法时收缩,合法时更新答案(while 外更新)
阶段 4:实现
java
public int lengthOfLongestSubstring(String s) {
int[] freq = new int[128];
int left = 0, ans = 0;
for (int right = 0; right < s.length(); right++) {
freq[s.charAt(right)]++;
while (freq[s.charAt(right)] > 1) { // 不合法:收缩到重新合法
freq[s.charAt(left)]--;
left++;
}
ans = Math.max(ans, right - left + 1); // 合法后更新答案
}
return ans;
}阶段 5:复盘记录到私人 cheatsheet
[LC 3] 无重复字符的最长子串 (中等)
题型:滑动窗口 / 求最长
触发信号:连续子串 + 状态可增量维护出现频率
最先卡:混淆了"子串"和"子序列",以为要用 DP
迁移:所有"求最长连续 XXX"类题 → 滑动窗口
对比题:LC 76(求最短)答案更新在 while 内一刷题最容易犯的错误
- 一上来就看最优解,导致没有自己的判断过程。
- 只记代码,不记为什么这题属于这一类。
- 做完题不复盘,第二天又像第一次见。
- 刷题速度过快,样例都没手推清楚就开始写。