跳到主要内容

LeetCode Hot 100 教程

LeetCode Hot 100 是面试高频题目的精选集,涵盖了算法面试中最核心的知识点。本教程按照题目类型进行分类,帮助你系统化地掌握算法与数据结构。

为什么刷 Hot 100

Hot 100 的价值在于:

  • 面试命中率高:这些题目是大厂面试的高频考点,覆盖面广
  • 知识点全面:涵盖了数组、链表、树、图、动态规划等核心数据结构与算法
  • 难度梯度合理:从简单到困难,循序渐进
  • 时间投入回报高:100 道精选题目,比盲目刷题更高效

教程目录

1. 基础技巧

  • 哈希 - 两数之和、字母异位词分组、最长连续序列
  • 双指针 - 移动零、盛最多水的容器、三数之和、接雨水
  • 滑动窗口 - 无重复字符的最长子串、找到字符串中所有字母异位词
  • 子串 - 和为 K 的子数组、滑动窗口最大值、最小覆盖子串
  • 技巧 - 只出现一次的数字、多数元素、下一个排列等

2. 线性和矩阵

  • 普通数组 - 最大子数组和、合并区间、轮转数组等
  • 矩阵 - 矩阵置零、螺旋矩阵、旋转图像、搜索二维矩阵 II
  • 链表 - 反转链表、环形链表、两数相加、合并 K 个升序链表等

3. 三大核心:树、图、搜索

  • 二叉树 - 中序遍历、最大深度、验证二叉搜索树、最近公共祖先等
  • 图论 - 岛屿数量、腐烂的橘子、课程表、实现 Trie
  • 回溯 - 全排列、子集、组合总和、N 皇后
  • 二分查找 - 搜索插入位置、搜索旋转排序数组、中位数问题

4. 进阶结构与算法

  • - 有效的括号、最小栈、每日温度、柱状图最大矩形
  • - 数组中的第 K 个最大元素、前 K 个高频元素、数据流中位数
  • 贪心算法 - 买卖股票、跳跃游戏等

5. 动态规划

  • 动态规划 - 爬楼梯、杨辉三角、打家劫舍、最长递增子序列等
  • 多维动态规划 - 不同路径、最小路径和、最长回文子串、编辑距离

刷题方法论

刷题三阶段

第一阶段:理解与模仿(1-2 周)

按分类顺序刷题,每道题先尝试 15-20 分钟,如果没有思路就看题解。重点理解:

  • 为什么这样解?
  • 这种解法的时间空间复杂度是多少?
  • 有哪些边界情况需要注意?

第二阶段:独立实现(2-3 周)

关闭题解,自己从头实现。即使知道思路,写代码时也会遇到很多细节问题:

  • 变量命名要清晰
  • 边界条件要仔细检查
  • 代码风格要整洁

第三阶段:举一反三(持续)

尝试一题多解,对比不同解法的优劣。思考:

  • 这道题的变形会是什么?
  • 类似题目有什么共同模式?

如何分析一道算法题

拿到一道题,建议按以下步骤分析:

1. 理解题意

  • 仔细阅读题目,提取关键信息
  • 明确输入输出的格式和范围
  • 处理特殊情况和边界条件

2. 分析数据规模

根据题目给出的数据规模,可以推断时间复杂度的要求:

数据规模可接受的时间复杂度
n ≤ 10O(n!), O(2^n)
n ≤ 20O(2^n), O(n² × 2^n)
n ≤ 100O(n³)
n ≤ 1000O(n²)
n ≤ 10^5O(n log n)
n ≤ 10^6O(n)
n ≤ 10^9O(log n)

3. 选择算法思路

根据数据规模和问题特征,选择合适的算法:

  • 有序数组 → 考虑二分查找
  • 子串/子数组 → 考虑滑动窗口
  • 求最值 → 考虑动态规划或贪心
  • 连通性问题 → 考虑并查集或 BFS/DFS
  • 括号匹配 → 考虑栈

4. 手动画图验证

在写代码前,用简单的例子手动模拟算法过程,验证思路是否正确。

5. 编写代码

先写主体框架,再补充细节。注意变量命名和代码风格。

6. 测试与调试

  • 用题目给的示例测试
  • 用边界情况测试(空输入、单元素、全相同元素等)
  • 用特殊输入测试

复杂度分析方法

时间复杂度:估算算法执行的基本操作次数,用大 O 表示法。

// O(n) - 单层循环
for (int i = 0; i < n; i++) { ... }

// O(n²) - 双层嵌套循环
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) { ... }
}

// O(log n) - 二分查找
while (left < right) {
int mid = left + (right - left) / 2;
// 每次将搜索范围缩小一半
}

// O(n log n) - 排序
Arrays.sort(arr); // 大多数排序算法

空间复杂度:估算算法使用的额外空间。

// O(1) - 只用常数变量
int a = 0, b = 1;

// O(n) - 使用与输入规模成比例的数组
int[] dp = new int[n];

// O(n) - 递归调用栈
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2); // 深度为 n
}

学习建议

每道题的标准学习流程

  1. 先思考再看题解:给自己 15-20 分钟尝试,培养独立思考能力
  2. 理解核心思路:不仅要看懂代码,更要理解为什么这样解决
  3. 手写代码:关闭参考,自己从头写一遍,加深记忆
  4. 分析复杂度:必须清楚时间和空间复杂度
  5. 总结归纳:记录这类题目的解题模式

常见错误类型

1. 边界条件处理

  • 数组为空或长度为 1
  • 目标值在数组范围外
  • 指针越界

2. 逻辑错误

  • 循环终止条件错误
  • 指针移动方向错误
  • 状态转移方程错误

3. 数据类型问题

  • 整数溢出:使用 long 类型
  • 浮点数精度:避免直接比较浮点数

4. 空指针异常

  • 访问链表节点前检查 null
  • 访问树节点前检查 null

刷题心态

  • 不要追求一次通过:面试时也很少能一次写对,关键是快速定位问题
  • 不要死磕一道题:超过 30 分钟没思路就看题解,效率更高
  • 注重质量而非数量:理解一道题比草草刷十道更有价值
  • 定期复习:使用间隔重复法,一周后、一月后复习做过的题目

参考资源