初学者:先建立题型感觉
你不需要一上来就背复杂模板。先知道“这道题为什么会想到双指针、DP、栈”,再跟着动画走一遍。
- 看每套心法的“识别信号”
- 点配套简单题,先看动画不急着写
- 去算法小游戏里把直觉玩出来
真正让人进步的不是刷题数量,而是看到一道题时,能判断它属于哪类问题、该用哪套骨架、哪里容易错。这个模块把高频算法收敛成六套可迁移的心法:先看懂,再会写,最后能讲给面试官听。
同一套心法,不是只给面试党背模板。它要同时解决“看不懂”“刷不动”“讲不清”和“迁移不了”四类问题。
你不需要一上来就背复杂模板。先知道“这道题为什么会想到双指针、DP、栈”,再跟着动画走一遍。
校招准备最怕东刷一道、西刷一道。这里把常见题收成专题,帮你从“会一道”变成“会一类”。
只会写代码还不够,研究生和高阶面试更看重抽象能力:为什么正确,复杂度如何,能不能换场景复用。
页面不做硬推销。免费内容负责让你看见方法,会员训练负责把方法练到能复述、能默写、能应对追问。
读心法、看图解题、玩小游戏。目标不是马上刷很多,而是建立清晰的解题地图。
每学一套模型,至少跟 3 道题:一道入门、一道人肉推演、一道变形题。
会员价值不只是多看内容,而是有人陪你把卡点问穿,把答案讲成面试官听得懂的话。
每套都按“识别信号、思考骨架、常见坑、配套题”组织。先建立模型,再回到题库练。
看到数组、字符串、链表里出现“成对比较、连续区间、原地处理”,优先想双指针。它的价值是把暴力枚举的两层循环,压成一趟可控移动。
# 对撞指针:有序数组里找一对
l, r = 0, n - 1
while l < r:
if 满足(l, r): return ...
elif 偏大: r -= 1
else: l += 1
给初学者的抓手:先别背四种写法,记住“指针移动必须排除一批不可能答案”。每移动一步,都要能说清楚为什么被排除的那部分不用再看。
DP 不是背公式,而是把一个大问题拆成一组更小的状态。只要状态定义清楚,转移方程通常会从“最后一步怎么来”里自然长出来。
# DP 五问:每次都按这个顺序想
状态是什么?
从哪些更小状态转移?
初始值是什么?
按什么顺序填表?
能否压缩空间?
给大学生的抓手:每做完一道 DP,把“状态定义”和“转移来源”写成一句话。面试官真正想听的不是代码多熟,而是你为什么这样定义状态。
回溯就是在一棵决策树上搜索。你要做的不是“乱试”,而是定义清楚每层在选什么、哪些选择合法、什么时候收集答案。
path.append(选项) # 做选择 backtrack(下一层) # 继续搜 path.pop() # 撤销选择
给初学者的抓手:把回溯画成树。每一层代表一个决策位置,每条边代表一次选择。你能画出来,就能写出来。
二叉树题的核心不是背遍历顺序,而是想清楚“当前节点要向父节点返回什么”。递归函数一旦定义准确,前中后序只是处理时机不同。
def dfs(node):
if not node: return 基准值
L = dfs(node.left)
R = dfs(node.right)
return 合并(L, R, node)
给研究生的抓手:很多树题可以看作结构归纳。先证明空树成立,再假设左右子树答案正确,最后证明合并后当前节点正确。
二分不只是“在数组里找数”。只要答案区间具有单调性,就可以在答案上二分:速度、容量、天数、阈值,都能变成可判定问题。
# 下界二分:找第一个满足 cond 的位置
l, r = 0, n
while l < r:
m = (l + r) // 2
if cond(m): r = m
else: l = m + 1
return l
给大学生的抓手:二分答案题要先写判定函数。“给我一个 x,我能不能判断 x 行不行?”能判断,再谈二分。
栈解决的是“最近的、还没闭合的东西”:括号、路径、表达式、下一个更大元素。单调栈尤其重要,它把很多看似要回头比较的题压成 O(n)。
# 单调栈:为每个元素找右边第一个更大的
stack = []
for i, x in enumerate(arr):
while stack and x > arr[stack[-1]]:
j = stack.pop()
ans[j] = i - j
stack.append(i)
给研究生的抓手:单调栈的本质是不变量维护。栈内元素保持单调,每个元素最多入栈出栈一次,所以总复杂度是 O(n)。
如果你刚入门,先走免费路径:读心法、看 3 道图解题、玩 1 个小游戏。如果你正在准备校招或复试,建议进入会员训练:让 AI 私教按题追问,直到你能独立写出代码并说清楚复杂度。
适合已经意识到“看懂题解”和“自己会写”之间有距离的人。会员不是卖更多文案,而是给你 AI 私教、通关训练和学习报告。