Skip to content

算法题

数据结构与算法的实战手册,从模板到经典题,从暴力到最优。

刷题方法论

先按专题刷透 → 再混合复习 → 计时模拟面试

刷题不是盲目堆量,而是有策略地系统性提高。推荐三阶段法:

阶段 1:专题突破(约 200 题)

按数据结构或算法技巧分类,集中刷同一类型题目,形成肌肉记忆。例如先把所有双指针题目做完,再进入滑动窗口。

推荐顺序

1. 数组与字符串(10-15 题)→ 熟悉基础
2. 链表(10 题)→ 掌握指针操作
3. 哈希表(10 题)→ O(1) 查找思维
4. 双指针(10 题)→ 对撞、快慢
5. 二分查找(10 题)→ 边界处理
6. 滑动窗口(10 题)→ 定长/不定长
7. 栈与队列(10 题)→ 单调栈引入
8. 树(15 题)→ 递归思维
9. 回溯(15 题)→ 组合/排列/子集
10. 动态规划(30 题)→ 五步法
11. 图论(15 题)→ BFS/DFS/拓扑
12. 贪心(10 题)→ 区间调度

阶段 2:混合复习(约 100 题)

打乱顺序做题,锻炼识别题型能力——看到题目能在 30 秒内判断属于哪类算法。

阶段 3:计时模拟(每周 2-3 次)

模拟真实面试场景:

  • 45 分钟内完成一道中等难度题(包括沟通、编码、测试全流程)。
  • 录屏回放,分析自己的表达和思路。
  • 找朋友/前同事做 mock interview。

知识地图

必备数据结构(按重要性排序)

模块内容难度高频
数组与字符串双指针、前缀和、差分⭐⭐⭐⭐⭐⭐⭐
哈希表计数、O(1) 查找⭐⭐⭐⭐⭐⭐⭐
链表虚拟头节点、快慢指针⭐⭐⭐⭐⭐⭐
栈与队列表达式求值、单调栈引入⭐⭐⭐⭐⭐⭐
遍历、BST、LCA⭐⭐⭐⭐⭐⭐⭐⭐
Top-K、堆排序⭐⭐⭐⭐⭐⭐
BFS/DFS、拓扑排序、最短路径⭐⭐⭐⭐⭐⭐⭐⭐

必备算法技巧

模块内容难度高频
双指针对撞、快慢、归并⭐⭐⭐⭐⭐⭐⭐
滑动窗口定长/不定长窗口⭐⭐⭐⭐⭐⭐⭐
二分查找边界处理、二分答案⭐⭐⭐⭐⭐⭐⭐
分治归并、快排、主定理⭐⭐⭐⭐⭐⭐
回溯组合/排列/子集模板⭐⭐⭐⭐⭐⭐⭐⭐
贪心区间调度、跳跃游戏⭐⭐⭐⭐⭐⭐
动态规划五步法、空间压缩⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
单调栈下一个更大元素⭐⭐⭐⭐⭐⭐
并查集路径压缩、按秩合并⭐⭐⭐⭐⭐⭐

排序与搜索

模块内容难度高频
排序算法比较/非比较排序全览⭐⭐⭐⭐⭐
搜索BFS、DFS、A*⭐⭐⭐⭐⭐⭐⭐

经典问题专题

模块内容难度
LeetCode Hot 100 精讲高频面试题精选⭐⭐⭐
LRU 缓存哈希 + 双向链表⭐⭐⭐
股票系列状态机 DP⭐⭐⭐⭐
打家劫舍线性/环形/树形 DP⭐⭐⭐
背包问题0-1/完全/多重背包⭐⭐⭐⭐

面试

模块内容难度
复杂度分析大 O 表示法、主定理
面试策略与代码模板五步法、沟通技巧

推荐刷题顺序

数据结构基础 → 算法技巧 → 经典问题 → 计时模拟
     |              |            |           |
  数组/链表      双指针/二分   DP/背包     Hot 100
  栈/队列/哈希   滑动窗口      股票/偷盗    面试策略
  树/堆/图       分治/回溯     LRU 缓存
                 贪心/单调栈
                 并查集

题型快速识别表

看到题目后 30 秒内应能识别:

题目关键词推荐算法
"两数之和" / "找出对"哈希表 / 双指针(排序后)
"无重复最长子串"滑动窗口
"最长回文"中心扩展 / 区间 DP
"下一个更大"单调栈
"前 K 个"堆 / 快速选择
"路径" / "迷宫"BFS / DFS
"依赖关系" / "课程表"拓扑排序
"出现次数"哈希 / 计数排序
"排序后"排序预处理
"动态变化最值"单调栈 / 单调队列
"树的最值"DFS + 后序遍历
"石子合并"区间 DP
"背包"0-1 背包 / 完全背包
"字符串匹配"KMP / Rabin-Karp
"无向图连通"并查集
"最短路径"Dijkstra / Floyd / BFS(无权图)
"判断环"DFS 三色标记 / 拓扑排序

面试 vs 竞赛的区别

维度面试竞赛
目标展示思维过程和编码能力AC 题目数量和速度
时间40-50 分钟 1-2 题1.5-5 小时 4-10 题
交流边想边说,展示推理独立思考
代码风格可读性优先效率优先
复杂度口述分析隐含在题目约束中
边界条件必须主动讨论自动判题
测试用例主动构造系统提供

推荐资源

刷题平台

学习资料

  • 代码随想录 — 系统刷题教程
  • LeetCode 宫水三叶 — 高质量题解
  • labuladong 的算法小抄 — 模板总结
  • 《算法(第 4 版)》— Sedgewick,Java 描述,入门友好
  • 《算法导论》(CLRS) — 学术经典,理论深入
  • 《剑指 Offer》— 面试专项
  • 《算法设计手册》— Skiena,工程导向
  • 《编程珠玑》— Jon Bentley,算法思维训练

视频课程

如何复盘

每道题做完后问自己三个问题

  1. 这道题的本质模型是什么?(如:滑动窗口求最值)
  2. 我是怎么从暴力解想到最优解的?(推理链路是否可复用)
  3. 有哪些边界用例我一开始没考虑到?

建议用 Markdown 或 Anki 记录错题,定期回顾。一道题做三遍,比三道题各做一遍效果好得多

三遍刷题法

  • 第一遍:思考 15 分钟无思路就看题解,理解后自己默写。
  • 第二遍(隔 3 天):不看题解,独立完成。卡住时回顾。
  • 第三遍(隔 1 周):尝试不同解法,比较优劣,思考变体。

常见题型代码模板速查

双指针(对撞)

python
def template(nums):
    l, r = 0, len(nums) - 1
    while l < r:
        # 处理逻辑
        if condition:
            l += 1
        else:
            r -= 1

滑动窗口

python
def template(s):
    l = 0
    cnt = defaultdict(int)
    for r in range(len(s)):
        cnt[s[r]] += 1
        while invalid(cnt):  # 窗口不合法时收缩
            cnt[s[l]] -= 1
            l += 1
        # 此刻 [l, r] 是合法窗口

二分查找

python
def template(nums, target):
    l, r = 0, len(nums)  # 注意 r 的取值
    while l < r:
        mid = (l + r) // 2
        if nums[mid] < target:
            l = mid + 1
        else:
            r = mid
    return l  # 第一个 >= target 的位置

BFS

python
from collections import deque
def template(start, target):
    queue = deque([(start, 0)])
    visited = {start}
    while queue:
        node, dist = queue.popleft()
        if node == target:
            return dist
        for neighbor in get_neighbors(node):
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append((neighbor, dist + 1))
    return -1

DFS(回溯)

python
def template(nums):
    result = []
    path = []
    def backtrack(start):
        result.append(path[:])  # 收集
        for i in range(start, len(nums)):
            path.append(nums[i])
            backtrack(i + 1)
            path.pop()
    backtrack(0)
    return result

动态规划五步法

python
def template(nums):
    # 1. 定义状态
    dp = [0] * len(nums)
    # 2. 初始条件
    dp[0] = nums[0]
    # 3. 转移方程
    for i in range(1, len(nums)):
        dp[i] = max(dp[i-1] + nums[i], nums[i])
    # 4. 计算顺序:从小到大
    # 5. 答案位置
    return max(dp)

单调栈

python
def template(nums):
    stack = []  # 存索引
    result = [-1] * len(nums)
    for i in range(len(nums)):
        while stack and nums[stack[-1]] < nums[i]:
            result[stack.pop()] = nums[i]
        stack.append(i)
    return result

并查集

python
class UnionFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [0] * n
    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]
    def union(self, x, y):
        px, py = self.find(x), self.find(y)
        if px == py: return False
        if self.rank[px] < self.rank[py]: px, py = py, px
        self.parent[py] = px
        if self.rank[px] == self.rank[py]: self.rank[px] += 1
        return True

心态管理

  • 刷题焦虑:每个人都觉得自己刷得不够。150-200 题足够大多数面试。
  • 记忆遗忘:遗忘是正常的,三遍刷题法解决。
  • 看题解挫败:第一次看题解是学习,不是失败。
  • 比较心理:不要看别人 AC 多少,按自己节奏走。
  • 面试紧张:面试时遇到没见过的题是常态——展现你的思考过程比答对更重要。

30 / 60 / 90 天计划

30 天(150 题)

  • 前 10 天:数组、链表、哈希、字符串(50 题)
  • 中 10 天:双指针、二分、滑动窗口、回溯(50 题)
  • 后 10 天:DP、树、图(50 题)

60 天(250 题)

  • 在 30 天基础上增加:LeetCode Hot 100 全部 + 剑指 Offer 全部 + 错题二刷

90 天(350 题)

  • 在 60 天基础上增加:Codeforces rating 1400+ 题目 + 公司高频题 100 道 + Mock Interview 20 次

基于 VitePress 构建 · 部署于 Cloudflare Pages