1. 代码随想录刷题指南:从入门到精通的系统化路径
作为一名经历过数百小时算法训练的老程序员,我深知系统化学习的重要性。这份刷题清单不是简单的题目堆砌,而是经过精心设计的成长路线图。它按照数据结构与算法的内在逻辑,将LeetCode和卡码网的经典题目组织成循序渐进的学习模块。
提示:建议初学者按照大纲顺序刷题,不要跳跃。每个专题需要彻底掌握后再进入下一阶段,避免"看似刷了很多题,实则没有形成体系"的困境。
1.1 为什么需要系统化刷题?
算法能力的提升就像建造金字塔,底层的基础决定了最终的高度。很多同学在刷题时容易陷入两个误区:
- 随机刷题:看到什么刷什么,导致知识碎片化
- 盲目追求数量:重复刷简单题,回避困难专题
这份大纲的价值在于:
- 每个专题都精选了最具代表性的题目
- 题目难度呈阶梯式上升
- 知识点之间具有强关联性
- 标注了ACM模式题目(卡码网),适合准备机试
2. 基础数据结构:构建算法思维的基石
2.1 数组专题(7题)
数组是最基础也是最高频的数据结构,重点掌握四种核心技巧:
2.1.1 二分查找(704题)
python复制def search(nums, target):
left, right = 0, len(nums)-1
while left <= right:
mid = left + (right-left)//2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
关键点:
- 循环条件用
left <= right而非left < right - 中间值计算防溢出写法
left + (right-left)//2 - 有序数组是二分查找的前提
2.1.2 双指针技巧
- 快慢指针:27题移除元素
- 左右指针:977题有序数组平方
- 滑动窗口:209题长度最小子数组
注意事项:滑动窗口的难点在于确定窗口收缩条件,建议先暴力解法再优化
2.2 链表专题(7题)
链表的操作关键在于指针的精确控制:
2.2.1 虚拟头节点技巧
python复制def removeElements(head, val):
dummy = ListNode(next=head) # 创建虚拟头节点
curr = dummy
while curr.next:
if curr.next.val == val:
curr.next = curr.next.next
else:
curr = curr.next
return dummy.next
使用场景:
- 可能修改头节点的情况(203题)
- 统一处理逻辑简化代码
2.2.2 环形链表检测(142题)
快慢指针法的数学原理:
- 设环外长度a,环内相遇点距环入口b
- 快指针路程=a+n(b+c)+b
- 慢指针路程=a+b
- 由2(a+b)=a+n(b+c)+b推导出a=(n-1)(b+c)+c
2.3 哈希表实战(8题)
哈希表的三种典型应用场景:
| 场景 | 例题 | 实现方式 |
|---|---|---|
| 快速查找 | 1.两数之和 | 字典存储值和索引 |
| 去重判断 | 202.快乐数 | 集合检测循环 |
| 频次统计 | 383.赎金信 | 数组模拟哈希表 |
避坑指南:使用数组代替哈希表时(如仅含小写字母),可以大幅提升性能
3. 核心算法专题:突破面试难关
3.1 二叉树全解析(28题)
3.1.1 递归三要素
以104题最大深度为例:
python复制def maxDepth(root):
if not root: # 终止条件
return 0
left = maxDepth(root.left) # 左子树深度
right = maxDepth(root.right) # 右子树深度
return max(left, right) + 1 # 当前节点处理
3.1.2 迭代法模板
层序遍历(102题)的标准写法:
python复制def levelOrder(root):
if not root:
return []
queue = collections.deque([root])
res = []
while queue:
level = []
for _ in range(len(queue)):
node = queue.popleft()
level.append(node.val)
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
res.append(level)
return res
3.2 动态规划系统突破(37题)
3.2.1 DP解题五步骤
- 确定dp数组含义
- 建立递推公式
- 初始化边界条件
- 确定遍历顺序
- 举例验证
以70题爬楼梯为例:
python复制def climbStairs(n):
if n <= 2: return n
dp = [0]*(n+1)
dp[1], dp[2] = 1, 2
for i in range(3, n+1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
3.2.2 背包问题分类
| 类型 | 特点 | 例题 |
|---|---|---|
| 01背包 | 物品选或不选 | 416题 |
| 完全背包 | 物品无限取用 | 518题 |
| 多重背包 | 物品有限个数 | - |
| 分组背包 | 物品分组互斥 | - |
关键区别:遍历顺序!
- 01背包:倒序遍历容量
- 完全背包:正序遍历容量
4. 进阶技巧:挑战大厂高频难题
4.1 单调栈精讲(5题)
适用场景:寻找下一个更大/更小元素
42题接雨水的双指针优化:
python复制def trap(height):
stack = []
res = 0
for i in range(len(height)):
while stack and height[i] > height[stack[-1]]:
bottom = stack.pop()
if not stack: break
left = stack[-1]
width = i - left - 1
h = min(height[left], height[i]) - height[bottom]
res += width * h
stack.append(i)
return res
4.2 图论实战(25题)
4.2.1 并查集模板
python复制class UnionFind:
def __init__(self, n):
self.parent = list(range(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):
rootX = self.find(x)
rootY = self.find(y)
if rootX != rootY:
self.parent[rootX] = rootY
4.2.2 Dijkstra算法实现
python复制def dijkstra(graph, start):
n = len(graph)
dist = [float('inf')] * n
dist[start] = 0
heap = [(0, start)]
while heap:
d, u = heapq.heappop(heap)
if d > dist[u]:
continue
for v, w in graph[u]:
if dist[v] > dist[u] + w:
dist[v] = dist[u] + w
heapq.heappush(heap, (dist[v], v))
return dist
5. 高效刷题方法论
5.1 题目分类训练法
- 第一遍:按专题顺序刷
- 第二遍:按题目类型刷(如所有二叉树DFS)
- 第三遍:随机抽题模拟面试
5.2 错题管理策略
- 建立错题本,记录错误原因
- 对每个错题进行三次重做:
- 当天立即重做
- 三天后再次重做
- 一周后最后检验
5.3 时间分配建议
| 阶段 | 每日时间 | 重点 |
|---|---|---|
| 基础 | 2小时 | 理解数据结构 |
| 强化 | 3小时 | 掌握算法模板 |
| 冲刺 | 4小时 | 模拟面试场景 |
我在带新人刷题时发现,坚持按照这个体系训练3个月的同学,算法面试通过率能达到80%以上。最重要的是养成每天刷题的习惯,哪怕只做一道题也要保持手感。