算法刷题笔记:动态规划与优先队列实战解析
1. 刷题笔记的价值与意义
作为一名程序员,我坚持刷算法题已经三年多了。2026年1月22日这天的刷题笔记特别值得记录,因为这天遇到的几道题目涵盖了多个经典算法模式。刷题不仅仅是应付面试的手段,更是锻炼编程思维的有效方式。
算法题就像健身房的器械训练,每道题都在针对性地锻炼特定的"思维肌肉"。通过系统性地记录和整理刷题笔记,可以清晰地看到自己的进步轨迹,也能在遇到类似问题时快速回顾解题思路。
2. 当日刷题题目概览
2.1 题目选择策略
我通常会按照"1简单+2中等+1困难"的比例来选择每日刷题组合。2026.1.22这天选择的题目是:
- 简单题:两数之和(经典热身题)
- 中等题:二叉树的中序遍历(递归与迭代实现)
- 中等题:最长回文子串(动态规划解法)
- 困难题:合并K个升序链表(优先队列应用)
提示:建议每次刷题都包含不同难度,这样既能保持信心,又能持续挑战自己。
2.2 刷题环境配置
我的刷题环境配置如下:
- IDE:VS Code + LeetCode插件
- 语言:Python 3.9(兼顾简洁与效率)
- 辅助工具:本地测试用例生成脚本
- 笔记工具:Markdown格式记录,同步到GitHub
# 本地测试用例示例 def test_two_sum(): nums = [2,7,11,15] target = 9 assert two_sum(nums, target) == [0,1]3. 题目详解与解题思路
3.1 两数之和的多种解法
这道经典题目看似简单,但蕴含着多种解题思路:
- 暴力枚举法:双重循环,时间复杂度O(n²)
- 哈希表法:空间换时间,时间复杂度O(n)
- 排序+双指针法:需要额外空间存储索引
def two_sum(nums, target): hashmap = {} for i, num in enumerate(nums): complement = target - num if complement in hashmap: return [hashmap[complement], i] hashmap[num] = i return []注意:哈希表解法要注意处理重复元素的情况,测试用例要考虑边界条件。
3.2 二叉树中序遍历的迭代实现
递归解法虽然简洁,但理解迭代解法对掌握栈的应用很有帮助:
def inorder_traversal(root): res = [] stack = [] curr = root while curr or stack: while curr: stack.append(curr) curr = curr.left curr = stack.pop() res.append(curr.val) curr = curr.right return res关键点:
- 使用栈模拟递归调用
- 先一路向左到底
- 处理节点后再转向右子树
3.3 最长回文子串的动态规划解法
这道题展示了动态规划的典型应用:
- 定义dp[i][j]表示s[i...j]是否为回文
- 状态转移方程:
- 基本情况:单个字符是回文
- 两个相同字符是回文
- 更长串:首尾相同且中间是回文
def longest_palindrome(s): n = len(s) dp = [[False]*n for _ in range(n)] res = "" for l in range(n): for i in range(n-l): j = i + l if l == 0: dp[i][j] = True elif l == 1: dp[i][j] = (s[i] == s[j]) else: dp[i][j] = (s[i] == s[j] and dp[i+1][j-1]) if dp[i][j] and l+1 > len(res): res = s[i:j+1] return res3.4 合并K个升序链表的优先队列解法
这道困难题展示了优先队列(堆)的典型应用场景:
import heapq def merge_k_lists(lists): dummy = ListNode(0) curr = dummy heap = [] for i in range(len(lists)): if lists[i]: heapq.heappush(heap, (lists[i].val, i)) lists[i] = lists[i].next while heap: val, i = heapq.heappop(heap) curr.next = ListNode(val) curr = curr.next if lists[i]: heapq.heappush(heap, (lists[i].val, i)) lists[i] = lists[i].next return dummy.next优化点:
- 使用元组存储值和链表索引
- 每次只push一个节点,保持堆的大小为O(k)
- 时间复杂度O(Nlogk),N是总节点数
4. 刷题技巧与经验分享
4.1 高效刷题的方法论
- 分类刷题法:按算法类型集中练习(如一周专攻动态规划)
- 五步解题法:
- 理解题意
- 列举可能的解法
- 选择最优解法
- 编写代码
- 测试与优化
- 错题本机制:记录错误原因和正确思路
4.2 常见错误与调试技巧
典型错误案例:
- 边界条件处理不当(空输入、单个元素等)
- 循环终止条件错误
- 指针/索引越界
- 特殊数据结构使用不当
调试技巧:
- 使用print语句输出中间变量
- 绘制数据结构变化图
- 编写测试用例覆盖边界条件
- 使用调试器逐步执行
4.3 刷题的时间管理
我个人的时间分配建议:
- 15分钟:理解题目和思考解法
- 20分钟:实现第一种解法
- 15分钟:优化和测试
- 10分钟:记录笔记和总结
如果超过这个时间还没思路,建议查看题解,但一定要自己重新实现一遍。
5. 刷题笔记的整理方法
5.1 笔记内容结构
每道题的笔记应包含:
- 题目描述(用自己的话复述)
- 解题思路(多种解法比较)
- 代码实现(带注释)
- 复杂度分析
- 相关题目链接
5.2 知识图谱构建
我使用思维导图工具将算法知识点连接起来,例如:
- 动态规划 → 背包问题 → 子集和问题
- 树 → 遍历方式 → 递归/迭代实现
- 图 → DFS/BFS → 拓扑排序
5.3 定期回顾机制
我设置了以下回顾周期:
- 次日:快速浏览前一天笔记
- 周末:总结本周刷题情况
- 月末:整理高频考点和薄弱环节
6. 从刷题到面试的转化
6.1 面试中的表达技巧
在面试中讲解算法题时要注意:
- 先明确问题边界和假设
- 讨论时间和空间复杂度权衡
- 考虑可能的优化方向
- 处理面试官的follow-up问题
6.2 实际工程中的算法应用
刷题中学到的算法在实际工作中的典型应用:
- 哈希表:缓存实现、去重
- 优先队列:任务调度
- 图算法:社交网络分析
- 字符串算法:搜索引擎
6.3 持续学习的资源推荐
我常使用的进阶资源:
- 《算法导论》(经典教材)
- LeetCode讨论区(优质题解)
- 算法可视化网站(直观理解)
- 技术博客(实战经验分享)
刷题三年多来,最大的体会是:算法能力的提升不是线性的,而是阶梯式的。每次突破一个瓶颈期,解决问题的能力就会上一个新台阶。2026.1.22这天的刷题笔记,记录了我在动态规划和优先队列应用上的新理解,也为后续的算法学习打下了更坚实的基础。