一、为什么需要算法刷题错题本

刚开始刷算法题的时候,很多人都会遇到这样的情况:明明之前做过类似的题目,但再遇到时还是不会做,或者写出来的代码漏洞百出。这其实就是因为没有系统性地整理和分析错题,导致同样的错误反复出现。

错题本的作用,就是帮助我们:

  1. 归类错题:把相似的错误整理到一起,方便后续复习。
  2. 分析原因:找出自己到底是思路问题、代码实现问题,还是对算法理解不透彻。
  3. 避免重复犯错:通过总结规律,减少未来犯同样错误的概率。

举个例子,你在做LeetCode 上的二叉树遍历问题时,可能会因为递归终止条件没写好导致栈溢出,或者迭代写法时忘记处理空节点。如果不记录下来,下次遇到类似问题还是会栽跟头。

二、如何有效归类错题

归类错题的核心是按算法类型和错误类型进行分类。我们可以用表格或者笔记软件(如 Notion、OneNote)来管理。

1. 按算法类型分类

  • 数据结构类:数组、链表、栈、队列、哈希表、堆、树、图等。
  • 算法类:排序、二分查找、DFS/BFS、动态规划、贪心、回溯、双指针等。

比如:

| 类别       | 题目                  | 错误原因                     |  
|------------|-----------------------|----------------------------|  
| 动态规划   | LeetCode 70.爬楼梯     | 递推关系没想清楚,初始条件错误 |  
| 双指针     | LeetCode 11.盛最多水的容器 | 左右指针移动条件判断错误      |  

2. 按错误类型分类

  • 逻辑错误:比如循环条件写错、边界条件没考虑。
  • 语法错误:比如 Python 的缩进问题、Java 的数组越界。
  • 优化不足:比如暴力解法超时,没想到更优解。
  • 理解偏差:比如题目意思理解错了,导致代码完全跑偏。

示例(Python 技术栈)

# 错误示例:LeetCode 15.三数之和(双指针解法)
def threeSum(nums):
    res = []
    nums.sort()
    for i in range(len(nums)):
        if i > 0 and nums[i] == nums[i-1]:  # 去重逻辑错误,应该放在找到解之后
            continue
        left, right = i+1, len(nums)-1
        while left < right:
            s = nums[i] + nums[left] + nums[right]
            if s == 0:
                res.append([nums[i], nums[left], nums[right]])
                # 忘记移动指针,导致死循环
            elif s < 0:
                left += 1
            else:
                right -= 1
    return res

修正后

def threeSum(nums):
    res = []
    nums.sort()
    for i in range(len(nums)):
        if i > 0 and nums[i] == nums[i-1]:  # 跳过重复元素
            continue
        left, right = i+1, len(nums)-1
        while left < right:
            s = nums[i] + nums[left] + nums[right]
            if s == 0:
                res.append([nums[i], nums[left], nums[right]])
                while left < right and nums[left] == nums[left+1]:  # 去重
                    left += 1
                while left < right and nums[right] == nums[right-1]:  # 去重
                    right -= 1
                left += 1  # 必须移动指针
                right -= 1
            elif s < 0:
                left += 1
            else:
                right -= 1
    return res

三、如何深入分析错误原因

归类之后,更重要的是分析为什么出错,而不仅仅是记录题目。

1. 错误原因拆解

  • 思路问题:是不是一开始就没想清楚?比如动态规划的状态转移方程没列对。
  • 代码实现问题:比如递归终止条件漏了,或者循环变量更新错误。
  • 边界条件:比如数组为空、链表只有一个节点等特殊情况没考虑。

示例(Java 技术栈)

// 错误示例:LeetCode 206.反转链表(递归解法)
public ListNode reverseList(ListNode head) {
    if (head == null) return null;  // 终止条件没问题
    ListNode newHead = reverseList(head.next);
    head.next.next = head;  // 问题:没有处理 head.next 为 null 的情况
    head.next = null;       // 导致空指针异常
    return newHead;
}

修正后

public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) {  // 增加 head.next == null 的判断
        return head;
    }
    ListNode newHead = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return newHead;
}

2. 对比优秀解法

有时候,你的代码可能能跑通,但不够优雅或高效。这时候可以去看看别人的解法,学习更优的思路。

比如,同样是反转链表,迭代写法可能更直观:

public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode next = curr.next;  // 保存下一个节点
        curr.next = prev;           // 反转指针
        prev = curr;                // 移动 prev
        curr = next;                // 移动 curr
    }
    return prev;
}

四、如何避免重复犯错

1. 定期复习错题

  • 每周抽时间回顾错题本,重新写一遍曾经出错的代码。
  • 重点关注那些反复出错的题目,直到完全掌握。

2. 模拟面试场景

  • 随机抽一道错题,限时 15-20 分钟完成,模拟真实面试环境。
  • 如果还是写不出来,就继续归类到“未掌握”列表,加强练习。

3. 总结通用解题模板

很多算法题有固定套路,整理出模板可以大幅减少错误。

比如二分查找的通用模板(Python):

def binary_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  # 注意 +1
        else:
            right = mid - 1  # 注意 -1
    return -1

4. 刻意练习薄弱点

如果你发现自己在动态规划图论问题上总是出错,就集中刷这类题目,直到形成肌肉记忆。

五、应用场景与技术优缺点

1. 应用场景

  • 面试准备:帮助快速查漏补缺,针对性提升。
  • 竞赛刷题:减少低级错误,提高解题速度。
  • 日常学习:系统化整理知识,避免学了就忘。

2. 技术优缺点

  • 优点
    • 提高刷题效率,减少无效练习。
    • 帮助形成系统化的解题思维。
  • 缺点
    • 需要额外时间整理,初期可能觉得麻烦。
    • 如果只是记录不复习,效果会大打折扣。

3. 注意事项

  • 不要贪多:每天记录 3-5 道典型错题即可,太多反而难以消化。
  • 注重质量:分析一道题的收获,比盲目刷 10 道题更有价值。
  • 保持更新:随着水平提升,早期的一些错题可能不再适用,可以适当清理。

六、总结

算法刷题的错题本,本质上是一个不断迭代优化的过程。通过归类、分析、复习,我们可以把“踩过的坑”变成“进步的阶梯”。

关键点回顾:

  1. 归类错题:按算法类型和错误类型整理。
  2. 分析原因:拆解思路、代码、边界条件等问题。
  3. 避免重复犯错:定期复习、模拟面试、总结模板。

坚持下去,你会发现,曾经的难题逐渐变得简单,刷题的速度和准确率也会大幅提升!