LeetCode 解题的思考策略与解题地图

什麽时间点该考虑 LeetCode 刷题?

▶「你有听过「白板题」吗?你知道技术考试在面试时会用什麽形式出现吗?」

How to: Work at Google — Example Coding/Engineering Interview

这张图是来自 How to: Work at Google — Example Coding/Engineering Interview ,由 Google 分享的的 Mock Interview 过程。技术面试这是许多人在面试前会有的焦虑,而透过刷题是用另一种「技术测验」方式,让我们习惯从题目来理解技术的过程。一般来说,技术面试题有两种考法:「线上/纸本技术面试测试(前测)」或「白板题(现场)」。线上/纸本技术面试测试着重的是「结果」,单纯就看最後的分数过不过作为最低的筛选门槛;而现场白版题着重的是「过程」,除了解法之外还有当下的思考脉络与持续优化的过程。

但是思考脉络与持续优化都不是可以短期恶补的,需要的是长期的训练与培养。因此,我不建议只把 LeetCode 当成是面试前的速成班,应该要视为长期持续练习的一种途径。所以如果在写程序的过程中有以下两种状况,那就很值得思考是否该适合踏入刷题的世界:

  • ① 准备面试的阶段
  • ② 想写出更好的程序

而在刷题的过程中训练的是「对於解题手法的想像力」,解法就是像是你的武器,当你面对一个问题的时候你可以拿出几种武器取决於你的经验与积累。所以对初学者而言首先要求的是写出可以动的程序,可是当遇到「效能」或是「更复杂的问题」时,这些技巧就成为你无形之中的优势。总而言之,我觉得刷题的重点是要找到一个适合自己的节奏,刷几题不是重点,重点是你从每一题中掌握了多少学到了多少而且持续的变强。

几种解题的策略

LeetCode 题目中从早期的 200 多题,到现在已经有 1000+ 题以上,刷题的难度也大大提升。对於刚开始尝试要开始刷题的时候通常未遇到以下盲点:

  • 不知道 从哪一个题目开始?
  • 不知道 要解多少题才够?
  • 不知道 是否真的理解?

而这些问题的背後,都是来自於不知道该如何有效刷题的焦虑感。

如何高效刷题,正确的解题顺序

早期坊间都会流传一些「只要刷满多少题,就能够通过某某公司技术面试关」的江湖传言,不过随着题目量与日俱增,透过「刷好刷满」的解题策略早已难以落实。因此,在 LeetCode 题目越来越像题海的同时,单纯地大量刷题策略反而会造成反效果。以下整理几种在不同情境时适合的刷题策略:

① 时间有限的话,从「热门题」开始刷

热门题指的是的是那些「面试」时常出现、面试官爱考的题目,在 LeetCode 中也有针对不同公司推出热门题组组合。所以如果你时间有限且方向明确的情况下,这是一种短期的策略。

② 搭配理论课程,从「分类题」个别刷

如果你还是学生或是正在读程序设计、资料结构、演算法之类的理论课程,那麽你可以搭配 LeetCode 中的题目分类,针对目前进行的章节选择相对应的题目进行刷题。理论课程教你的语法及归纳後的方法,更需要搭配实作练习才能学得好。

③ 长期持续锻链,从「难易度」逐步刷

最後一种是将 LeetCode 当成是一种长期持续练习题库的话,那我建议打散热门与分类这两个的维度,从无差别的方式进行刷题,把重点放在「解题」的过程中。虽然说无差别,但还是需要有个顺序进行,不然一开始遇到难题就卡关怎麽办。因此,我们会议可以使用 LeetCode 提供的「难易度」与「通过率」两个指标排序,从简单且很多人都通过的题目慢慢往比较难的题目开始逐步进行。

刷题的四个阶段

除了「解题顺序」之外,如何最大化一个题目的效益也是刷题过程中重要的关键。比起一题解完就换下一题这样的方式,我们更建议花多一点在一个题目中,尽可能地持续迭代、持续优化并且思考沈淀,让你从一个题目掌握到更深更广的效益。就如同我们前面所讲的,刷几题不是重点,重点是你从每一题中掌握了多少学到了多少而且持续的变强。

动手之前先思考 → 初探直觉解 → 刻意优化 → 举一反三

接着当开始进入「一个题目」的解题过程时,我会建议可以分成几个阶段:

动手之前先思考

快速读完题目知道,先确保题目的 Input、Output 与要求分别是什麽之後。请先不要就贸然的开始写程序码,应该是先思考一下大概的解题步骤以多想几种不同的策略,这个时候可以搭配虚拟码(pseudocode)或程序流程图辅佐。

初探直觉解

第二步就可以尝试把刚刚想到的策略付诸实现,我会建议可以先从「直觉解」、「穷举法」甚至是「暴力法」开始着手,在不要考虑效能的情况下先求可以逻辑正确可以跑出答案即可。

刻意优化

产生完第一个解法之後,接着就可以从直觉解当中进行重构(Refactoring),尝试从原本的解法中挑出可以优化的地方来改进。一般来说,程序的优化可以分为「更精简的程序码」或「更快地执行速度」两个角度下去着手。但一个题目能不能马上想到可以优化的空间,在刚开始是需要「刻意」练习的,有时候可能比想像中更困难。因为脑袋的思考会有先入为主的观念,有时候不容易跳出既有的框架。所以我会建议这段可以不用急,当写完一个题目之後可以三个小时、三天,甚是是三周之後再回来看同一个题目,把它当成新的题目重新解解看,反而更容易写出不一样的解法。

以我的经验来说,一个题目至少可以尝试到三到五种的解法。这样的效益比起单纯的解之外,更多了一层「迭代优化」的培养。

举一反三

最後当你从一个题目离开後,可以试着解类似题,并且从这个题目的解法「迁移」到另一个类似题中。在 LeetCode 有很多类似的题目,或是一个题目的进阶版。从这样的练习你,你会默默地发现这些看似类似或进阶的题目背後都有一些有趣的转化,而这个转化就是在培养能不能「迭代优化」的过程。


嗨,大家好!我是维元,一名擅长网站开发与资料科学的双栖工程师,斜杠於程序社群【JSDC】核心成员及【资料科学家的工作日常】粉专经营。目前在 ALPHACamp 担任资料工程师,同时也在中华电信、工研院与多所学校等单位持续开课。拥有多次大型技术会议讲者与竞赛获奖经验,持续在不同的平台发表对 #资料科学、 #网页开发 或 #软件职涯 相关的分享,邀请你加入 订阅 接收最新资讯。


<<:  02. Hello x Test x Test Pyramid

>>:  Render Element(Day3)

番外篇 - 波皮辣椒那你会修电脑吗仙姑狗

哈罗~ 大家好 相信看到标题的人应该都很困惑 这什麽名字啦~ 嘿 没错~ 这其实是我们的队名XD 好...

HTML笔记(05)-HTML基本语法

前面说了一堆废话(但我觉得应该是颇需要厘清的架构吧~), 现在就把HTML的内容物列出来真正踏进去撰...

VSCode 套件推荐系列 - 下

最後一篇,持续来介绍 VSCode 的套件,让你靠一套文字编辑器在路上横着走! CodeSpellC...

Day26条件运算式if... else(JavaScript)

各式if else写法 if... else最简单的型态就是长这样 if 条件=true才会执行代码...

行动商务系统设计与开发!

职训局的课程目前已上了3天课,目前还是在新手学习阶段,初接触visual studio程序,试着使用...