Leetcode之 Hot 100
如何高效刷 Hot 100?
1 按专题刷:不要随机刷。选择一个专题(如“动态规划”),集中刷 5-10 道题,总结规律和模板。
2 先思考,后看解:给自己 15-30 分钟独立思考,想不出来没关系,但一定要有自己的思路。然后看题解,理解最优解法的精髓。
3 画图分析:对于链表、二叉树、递归、动态规划等问题,动手画图能极大地帮助理解。
4 反复练习:过一段时间(如一周后)重新做一遍之前做过的题,确保真正掌握,而不是“背答案”。
5 总结模板:很多题有通用解法。例如:
回溯模板:选择 -> 递归 -> 撤销选择。
二叉树递归模板:处理当前节点 -> 递归左子树 -> 递归右子树。
动态规划步骤:定义状态 -> 推导状态转移方程 -> 确定初始条件 -> 计算顺序。
专题
1. 哈希表
核心思想:利用 O(1) 的查找时间,用空间换时间,常用于快速查找、计数或去重。
经典例题:
- 两数之和 - 哈希表记录遍历过的数字和索引。
- 字母异位词分组 - 将排序后的字符串作为哈希表的键。
- 最长连续序列 - 利用哈希集合快速判断数字是否存在。
2. 双指针
核心思想:使用两个指针协同遍历,常用于数组/链表操作,优化时间复杂度。
经典例题:
- 盛最多水的容器 - 左右指针向中间移动,每次移动高度较小的那个。
- 三数之和 - 排序后固定一个数,转化为两数之和问题,用双指针寻找。
- 接雨水 - 左右指针记录左右最大值,按较小一边计算雨水。
3. 滑动窗口
核心思想:维护一个窗口,通过移动左右指针来找到符合条件的子串/子数组。
经典例题:
- 无重复字符的最长子串 - 用哈希集合记录窗口内字符。
- 最小覆盖子串 - 用哈希表记录需要匹配的字符数量。
- 找到字符串中所有字母异位词 - 固定长度的滑动窗口。
4. 链表
核心思想:掌握虚拟头节点、快慢指针、反转链表等技巧。
经典例题:
- 两数相加 - 模拟加法,注意进位。
- 合并两个有序链表 - 递归或迭代合并。
- 环形链表 - 快慢指针判断是否有环。
- 反转链表 - 迭代或递归反转。
- 相交链表 - 巧妙的双指针走法。
5. 二叉树
核心思想:熟练掌握递归和迭代的遍历方式(前序、中序、后序、层序)。
经典例题:
- 二叉树的中序遍历 - 递归或迭代(使用栈)。
- 对称二叉树 - 递归比较左右子树。
- 二叉树的最大深度 - 递归求深度。
- 翻转二叉树 - 递归交换左右子树。
- 二叉树的层序遍历 - 使用队列进行 BFS。
6. 回溯算法
核心思想:通过递归尝试所有可能,在“岔路口”做出选择,遇到“死路”时回退。
经典例题:
- 全排列 - 经典回溯,使用 used 数组标记已使用元素。
- 子集 - 回溯或迭代。
- 单词搜索 - 二维平面上的回溯。
7. 动态规划
核心思想:将复杂问题分解为简单子问题,存储子问题的解以避免重复计算。
经典例题:
- 爬楼梯 - 经典入门题,dp[i] = dp[i-1] + dp[i-2]。
- 买卖股票的最佳时机 - 记录历史最低价。
- 单词拆分 - dp[i] 表示前 i 个字符能否被拆分。
- 打家劫舍 - dp[i] = max(dp[i-1], dp[i-2] + nums[i])。
- 完全平方数 - dp[i] = min(dp[i], dp[i - j*j] + 1)。
8. 栈与队列
核心思想:利用栈的 LIFO 和队列的 FIFO 特性解决问题。
经典例题:
- 有效的括号 - 使用栈匹配括号。
- 柱状图中最大的矩形 - 单调栈。
- 最小栈 - 设计一个支持获取最小值的栈。
9. 二分查找
核心思想:在有序集合中通过比较中间元素来快速缩小搜索范围。
经典例题:
- 寻找两个正序数组的中位数 - 难题,本质是寻找第 k 小数。
- 搜索旋转排序数组 - 在局部有序的数组中进行二分。
10. 图论
核心思想:DFS/BFS 遍历,并查集处理连通性问题。
经典例题:
- 岛屿数量 - DFS/BFS 淹没岛屿。
- 课程表 - 拓扑排序判断有向图是否有环。