刷题到最后,我才发现:真正拉开差距的,是这 5 种编程能力

0 阅读10分钟

想系统提升编程能力、查看更完整的学习路线,欢迎访问 AI Compass:github.com/tingaicompa… 仓库持续更新刷题题解、Python 基础和 AI 实战内容,适合想高效进阶的你。

刷题到最后,我才发现:真正拉开差距的,是这 5 种编程能力

很多人看到我整理的 coding,第一反应通常都是一句话:

“你这不就是在刷题吗?”

如果只看目录,这么理解也不奇怪。毕竟后面确实是一道道编程题,从两数之和、滑动窗口、链表、二叉树,到动态规划、图论、Trie、LRU 缓存,一路排到了 107 题。

但把这件事从头到尾做完之后,我越来越确定一件事:

真正拉开编程能力差距的,从来不是你刷了多少题,而是你有没有借这些题,把一套稳定的问题解决能力练出来。

这也是我后来重新看待这 107 道题的原因。

它们对我来说,已经不是一份普通题单,也不是一堆零散题解,而是一套非常压缩、非常直接的编程训练场。题目只是表面,底层训练的其实是另外几件更重要的东西:抽象能力、模式识别、复杂度意识、数据结构选择、还有把思路讲清楚的能力。

一、我为什么会认真整理这 107 道编程题

107道编程题模块化成长路径思维导图

我一开始做这件事,并不是为了单纯积累“刷题数量”。

恰恰相反,我是因为越来越不满意那种碎片化刷题方式,才决定把它系统整理出来。

很多人学编程题,路径都差不多:

  • 找一个热题清单
  • 每天做几道
  • 不会就看题解
  • 看懂了就算过
  • 过几天再遇到变形题,继续不会

这种学习方式最大的问题,不是题不够多,而是每道题都像孤岛

你可能做过两数之和,也做过无重复字符的最长子串,做过岛屿数量,做过零钱兑换,甚至连 LRU 缓存都看过题解。但如果这些题在你脑子里只是题号和答案,而不是模式和方法,那它们很难真正沉淀成能力。

所以后来我在整理 1.coding 这部分内容时,最在意的就不再是“还差多少题”,而是另外一个问题:

这些题,能不能被组织成一条清晰的能力成长路径?

从结果上看,这 107 道题最终覆盖了 15 个核心模块:

  • 哈希表
  • 双指针
  • 滑动窗口
  • 字符串
  • 链表
  • 栈与队列
  • 二叉树
  • 二分查找
  • 回溯算法
  • 贪心算法
  • 动态规划
  • 图论
  • 堆与优先队列
  • 前缀树
  • 高级技巧

当这些内容被放到同一条线上之后,我才真正感受到,编程题的价值从来不在于“这道题会不会”,而在于“这道题背后的那一类问题,你会不会”。

二、写到后来我才发现,这 107 道题真正训练的是 5 种底层能力

编程模式识别雷达图,开发者指向核心模块

开发者在工作台挑选数据结构模型

如果只把编程题理解成面试准备,其实有点可惜。

因为当你真的把一套高频题系统走下来,会发现它训练的根本不只是应试反应,而是写代码时最核心的那几种能力。

1. 模式识别能力

这是我认为刷题最容易被低估、但又最有复利的一项能力。

真正厉害的人,看到题目不是先想“我做过没有”,而是先判断:

  • 这是哈希表问题,还是双指针问题?
  • 这是在维护一个窗口,还是在枚举搜索空间?
  • 这是 DFS/BFS,还是 DP/贪心?
  • 这是状态设计问题,还是数据结构设计问题?

比如:

  • 两数之和,训练的是哈希表的互补查找模式
  • 最小覆盖子串,训练的是滑动窗口里“扩张 + 收缩”的控制能力
  • 岛屿数量、太平洋大西洋水流,训练的是图搜索的建模方式
  • 零钱兑换、最长公共子序列,训练的是动态规划的状态设计
  • LRU 缓存,训练的是“哈希表 + 双向链表”的结构组合能力

一旦你开始用“模式”看题,而不是用“题号”看题,刷题这件事的回报会突然变高很多。

2. 数据结构选择能力

我后来越来越觉得,很多题目的本质,其实不是算法有多花哨,而是你会不会选对数据结构。

写代码的人都知道,很多时候效率差距不是出在你写不写循环,而是出在你到底用了什么结构来组织信息。

这 107 道题里,反复在训练的就是这件事:

  • 什么时候该用 dict 做 O(1) 查找
  • 什么时候该用 set 去重和判存在
  • 什么时候该用 deque 维护队列和单调结构
  • 什么时候该用堆去处理 Top-K 和动态最值
  • 什么时候只能上树、图、Trie 或链表这种更明确的结构

很多人把编程题做得很“累”,本质上不是因为不会写,而是因为一开始就没选对结构,后面只能靠更多代码硬撑。

而一套系统题做下来,你会越来越敏感:题目一出来,先想结构,再想流程。

这是非常重要的代码能力。

3. 复杂度意识

这是我认为编程题和普通练习题最大的区别之一。

很多题如果只追求“能跑通”,其实并不难。真正有门槛的是,你要在有限时间和空间里,把它写成一个更合理的解。

这背后训练的就是复杂度意识。

比如:

  • 暴力双循环为什么不行
  • 为什么线性扫描要尽量改成哈希查找
  • 为什么有些题只能接受 O(log n) 的二分思路
  • 为什么有些搜索题必须剪枝,否则会指数爆炸
  • 为什么动态规划里状态数量一旦设计错,整题复杂度就直接失控

我自己在整理这些内容时,越来越明显地感觉到:复杂度分析不是附属环节,它就是思考过程本身。

很多题如果你说不清为什么要这样优化,其实也说明你还没有真正吃透。

4. 从暴力到最优的优化链路

这是我在写每一道题时都特别想保留下来的部分。

我一直不太喜欢那种上来直接贴最优解的题解,因为它会给人一种错觉,好像答案是凭空跳出来的。

但真实的思考过程从来不是这样的。

更自然、也更有训练价值的路径应该是:

  1. 先接受最直观的暴力思路
  2. 找到它的性能瓶颈
  3. 判断瓶颈属于查找、重复计算、状态维护,还是搜索空间过大
  4. 再选择合适的工具去优化

比如两数之和,从双循环到一遍哈希表; 零钱兑换,从递归爆搜到记忆化搜索或 DP; LRU 缓存,从普通容器模拟到哈希表加双向链表。

这条“从直觉到最优”的链路,我认为比最后那几行代码更有价值。

因为真正的编程能力,不是见过答案,而是能自己把答案推出来。

5. 表达能力和工程感

这一点很多人容易忽略,但我自己越来越看重。

编程题做到后面,你会发现真正拉开差距的,已经不是会不会写,而是你能不能把思路说明白。

你能不能清楚地说出:

  • 我为什么先想到暴力法
  • 性能瓶颈在哪里
  • 为什么这个数据结构合适
  • 这个优化为什么成立
  • 时间复杂度和空间复杂度分别是多少
  • 如果题目变形,我的解法还能怎么改

这其实已经不是单纯刷题了,而是在训练一个工程师很核心的能力:结构化表达问题和方案。

而这类能力,一旦建立起来,不只对面试有用,对日常开发、方案设计、代码评审同样有用。

三、为什么我会觉得这套内容有价值,不只是因为题多

代码优化路径与对应时间复杂度对比图

如果只是想证明“我做过很多题”,其实根本没必要把这件事做得这么完整。

真正让我愿意持续整理下去的,是我越来越确定:这套内容确实能帮人少走很多弯路。

因为它不是把 107 道题简单堆在一起,而是尽量把每一题都写成一个可复用的训练单元。

我在这套内容里一直尽量保留这些部分:

  • 题目描述和约束条件
  • 边界用例
  • 思路引导
  • 从暴力法到优化解的推导过程
  • 多解法对比
  • 复杂度分析
  • 面试现场怎么讲
  • 工程实战里它对应的意义
  • 举一反三和课后小测

我这样写,不是为了把文章拉长,而是因为我越来越相信:

真正值得沉淀的编程内容,不是只告诉别人“答案是什么”,而是让别人知道“答案是怎么来的,下次又该怎么自己想到”。

这也是我觉得这套内容相对普通题解更有优势的地方。

它更强调方法,不只是结果; 更强调链路,不只是结论; 更强调迁移,不只是记忆。

四、如果只用一句话总结这 107 道编程题的作用

开发者在白板讲解代码思路推导过程

那我现在会很明确地说:

它们不是在训练我“会做更多题”,而是在训练我遇到陌生问题时,如何更快完成建模、选结构、控复杂度、写出清晰方案。

这是完全不同的一件事。

前者更像记忆和熟练度,后者才更接近真正的编程能力。

我后来越来越能理解,为什么很多人题刷得不少,能力却不稳定。因为如果刷题只停留在“看懂答案”和“复现代码”这一步,那积累出来的往往只是熟悉感,不是方法感。

而真正有长期价值的,一定是后者。

五、写到最后,我真正想留下来的其实不是题解,而是一种看问题的方式

这篇文章写到这里,我反而越来越不想把 MossDev/1.coding 简单定义成“算法题目录”。

它当然是编程题内容,但它更像是我对“编程能力到底怎么练出来”这件事的一次集中回答。

如果一定要说它最核心的意义,我会觉得是这三件事:

  1. 让零散题目变成结构化训练
  2. 让刷题从记答案,变成练方法
  3. 让编程题最终回到真实的代码能力上

所以现在如果再有人问我,这 107 道题到底有什么作用,我大概不会再回答“面试高频题”这么简单了。

我更愿意说:

它们是一次非常高密度的编程思维训练。

题目只是入口,真正被训练出来的,是你面对复杂问题时的反应方式。

而这,可能才是刷题这件事最值得投入的地方。


如果这篇内容对你有帮助,推荐收藏 AI Compass:github.com/tingaicompa… 更多系统化题解、编程基础和 AI 学习资料都在这里,后续复习和拓展会更省时间。