讨论/综合讨论/如何写好题解?/
如何写好题解?

有的题目感觉自己已经能够很好的理解并解决,但是在尝试写题解的时候还是不知如何写好,想问一下一般好的题解是按照怎样的思路去写的?

展开讨论
nanana发起于 2020-01-11
最近编辑于 2020-01-13
共 1 个讨论

我经常写题解,所以分享一下写题解的思路与感想。

1、标题

标题我一般起名为这篇题解的思路,不同思路用顿号分割,例如 “暴力求解、动态规划”。或者用一句尽量简短的话来概括解这个问题的关键点,例如:“并查集求连通分量”。然后可以括弧加上你写的参考代码使用的语言,现在我的题解使用的参考代码的语言,一般我会写在题目的标签里。

这样起名的原因是方便让读者知道我这篇题解在说什么,是不是他们所需要的。

下面说一下题解内容。

2、格式

格式要非常清楚,这样看的朋友看起来会比较舒服。

格式参考官方题解,以 “方法一:”、“方法二” 来区分使用的不同方法,除非个别很基础或是专门考查一个知识点(例如 “快慢指针”)的问题,一道问题一般来说会有不同的解法。

写这些解法的时候,一般是层次递进的,首先先写暴力解法(如果有的话)。其实很多问题都来自暴力解法的优化,暴力解法的代码我一般是能写就尽量写,太麻烦的,不可实现的就不写了。写好暴力解法能够帮助思考清楚很多编码细节,再引出优化的写法就非常自然了。

3、题解内容

第 1 部分:描述思路

每个方法先说思路,再给出参考代码。

除非是从头开始介绍这个知识点,其余一般都只写思路,依然是尽量 “言简意赅”。用一段话,或者是分条目:

  • 条目 1
  • 条目 2

这样的格式写出来。这些条目一般罗列了:

  • 自己是怎么想到这个思路,是否和以前做过的某些问题有联系;
  • 注意到题目中给出的数据的特点、范围,所以采用了什么样的算法和数据结构;
  • 需要特别注意的地方:特殊测试用例判别;
  • 还有一些坑,自己一开始没有想到什么什么,提交了以后发现有个测试用例没有过,因此补充了什么什么,最后得到 Accept。

视情况展示 PPT 或者手写稿

很多问题在展示思路的时候,可能文字说不太清楚,我采用的方式一般画图,或者是制作 PPT 来展现思路。「力扣」的题解编辑器有一个这样的功能,是我很喜欢的,那就是使用 <> 这种语法,在两个尖括号之间加上图片地址,就能制作出 PPT 的效果。例如:

<![40-1.png](https://pic.leetcode-cn.com/5a8ad63b91ea09d46ac0b44cbf3325c2a3c2199ec232ec562135fbcf2ea9e70d-40-1.png),![40-2.png](https://pic.leetcode-cn.com/a470bcb582807c465ec03accfb29f204caab1438750e6fc5b029eb22700d7079-40-2.png)>

很多算法其实用动画来展示非常形象,当然这样做比较费时间。

还有一种做法,我个人认为效果其实更好。展示解决问题的手稿,注意一下字迹工整即可。很多时候我们做题就得在纸上写写画画,就展示这个过程是比较省时省力且更直接。

第 2 部分:给出参考代码

这部分内容蛮重要的,因为有些思路用文字的确说不清楚。而代码是最有说服力的,很多时候看题解的朋友也主要是来看代码的。这里简单说一下写题解代码和做周赛或者自己做练习代码的不同。

我的标准是:只要是代码想要被别人看到的,全部按照写工程时候的编码规范来写。

这一点和做周赛不一样,做比赛其实维度其实不多,代码首先要能得到 Accept,然后错误提交越少,使用时间最少就能得到一个不错的名次。但是代码评测系统无法检测到代码的命名是否见名知义、代码的可读性、扩展性、是否有恰当的注释、代码复杂度是否如题规定,而这些维度作为一名软件工程师来说,我觉得是相当重要的。

因此,展示出来的代码我都会多看几眼:

1、首先是代码格式化;
2、能封装的方法就尽量封装,以体现主干逻辑;
3、逻辑之间有层次关系的,加一行空格(这一点我做得比较随意,没有分的那么细);
4、不用一些有碍于理解的表达,例如:nums[i++]、一些三目运算符表示;
5、恰到好处的代码注释,一般在理解代码的难点、逻辑关键点和反常规操作的处加上代码注释。

建议参考的编码规范是:

这是我以前的领导和团队帮助我养成的习惯。这些编码规范内容很多,但遵守代码规范我个人觉得完全没有负担,不需要专门学习,只需要通过工具纠错学习即可。我的做法是:在集成开发环境里面安装相关插件,这些插件在大部分情况下都能够给出合理的修改建议,是学习编码的有效助手,犹如身边坐着一位好老师。如果有些朋友想练习白板编程,可以写完白板以后,再放到 IDE 工具里面去优化一下。

在这里吐槽一下力扣这个编辑器不太好的一点。

image.png

导致很多朋友不标注代码所使用的语言,代码都不能高亮显示,很影响阅读体验,此处手动艾特「力扣」产品经理。

另外,注意到 “混合代码块” 功能,我个人觉得非常棒,可以通过选项卡展示不同语言的参考代码,很节约空间,使用体验非常棒!这一点和上面“幻灯片”展示一样,都是「力扣」编辑器的特色,其它网站没有。

image.png

另外还可以录制视频题解哦,这个方式最省时间,也很锻炼人。

第 3 部分:给出复杂度分析

最后给出复杂度分析:包括时间复杂度、空间复杂度。依然是参考官方题解,先给出结论,然后用简短的一句话解释(如果结论很显然,可以不解释)得到这个复杂度分析的理由。

有些比较 “复杂的” 复杂度分析,例如 “回溯算法”、“并查集”,我一般没有写,或者是留着空请大家帮我分析。

复杂度分析是很重要的一块,通过复杂度分析,有可能发现自己代码中的不足之处。有些代码只有一行,但事实上,复杂度可能是线性的,例如 Python 的 str.index('a') 方法。

从暴力解法,到优化解法,一般都是 “以空间换时间”,在不同的方法之间,通过复杂度分析就能很清晰地比较它们之间的不同。


下面推荐几个我个人觉得写题解写得非常不错的朋友,欢迎大家围观:

最后可以参考一下「力扣」官方编写的「力扣编辑器」使用说明,注意文后有 “中文文案排版指北” 与 “Markdown 语法官方文档”。

32