如何准备LeetCode竞赛?

对很多初学者来说,在解决算法问题时,思维往往会混乱。有时他们认为某个问题涉及到动态规划的知识点,然后写的代码越来越乱。最后,在查看讨论区时,他们才发现这个问题其实可以使用栈来解决。其实,刻意练习算法并不会起作用,我们需要遵循科学的方法。 以下给出的经验和建议对于新手算法学习者,或者那些在大学期间没有参与ACM、希望在业余时间提高算法能力的人非常有帮助。这只是供参考。

  1. 算法并不是智商竞争 算法并非纯粹的智商竞技。认为高智商的人一定会非常熟练,较低智商的人肯定会失败,这种假设是错误的。算法是一种技能,是通过科学和理性的方法可以训练出来的能力。当然,一个人的智商水平确实会有影响,但这种先天因素无法改变,而科学和理性的方法对每个人都是开放的。因此,首要点是认识到算法不仅仅由智商决定,也可以通过后天训练获得。

  2. 难度应该逐步提升 有一些学生在解决问题时喜欢一蹴而就,认为只要他们能解决最难的问题,其余的就变得小菜一碟。这种急于求成的心态是不可取的。 算法训练是一项系统性的工程,需要逐渐提升。过于急功近利反而会轻易导致在解决困难问题时产生失败感,造成适得其反的效果。 还记得我有一个同事曾经做过类似的事情。当我们第一次听说LeetCode时,我们就想试试看。他登录后,他选择了一个在难题中更加难的问题。结果,他想了很长时间都解决不了,这让他感到非常沮丧。 你会发现这种方法非常低效。即使你解决了那个问题,也不意味着你可以解决其他问题。合理的方法是逐步前行。 如果你已经有了基础,而且非常熟练,解决一个简单的LeetCode问题只需要几分钟的时间。这不会花费你太多的时间。 如果你解决简单问题需要很长时间,那就说明你的熟练程度不足。所以,你应该从简单的问题开始,然后再到中等难度的问题,最后再到难题。 这里有一句话要告诉你。目前,美国科技巨头的算法评估难度很少超过LeetCode的中等难度。难度的上限基本上是LeetCode中等难度题目里的中等难度(在中等难度的LeetCode问题中也有不同的级别)。如果你能在20分钟内解决这个难度的问题,你基本上在美国科技巨头的算法面试中不会有什么障碍。

  3. 按照算法的分类来选择问题 在选择问题时,除了逐渐提高难度外,还可以按照算法进行分类。 基本的算法数据结构是有限的。例如,链表、二叉树、二叉搜索、动态规划、哈希表等。 我喜欢按照算法的分类选择练习问题。例如,在某段时间内,我只做链表的问题。当我几乎做完这些问题后,我就转向二叉树的问题。这种方法可以显著提高解题的速度,并取得更好的结果。 首先,连续练习同一类型的问题能够让你不断巩固并加深理解。 其次,你可以更全面地接触这种数据结构和算法的各种变体,这将促使你对数据结构和算法有更全面和深入的理解,从而提高学习效率。 因此,在一段时间内,连续练习某一特定类别的问题可以达到事半功倍的效果。 当然,当你的能力相对强时,你可以以混合的方式练习问题,这可以更好地训练你思维的灵活性和适应性。然而,在早期阶段或者你的能力相对较弱时,最好根据分类来选择问题。

LeetCode解题方案三步法:

实际解题时,你可以按照以下三步进行。注意,得到问题后,不要立即开始,而是要记住以下三个步骤,然后逐步进行。

  1. 理解问题 有些问题非常明确。他们直接告诉你需要解决的是什么问题,问题的陈述甚至可能包括需要使用的相应数据结构和算法。但是,有些问题相当模糊。看了很长时间,你仍然不明白需要解决的到底是什么问题,以及可以使用哪种算法和数据结构。因此,在看到问题后,你首先确保你已经清楚地理解了它。 我的经验是,当我得到一个问题时,我会花5分钟的时间。如果5分钟内还不能理解,我就会标记它,然后留到后面再说。否则,这会大大影响我做题的心情。然而,就LeetCode而言,这样的问题并不多。通常,你可以在5分钟内理解大多数问题。

  2. 分析并推导出解决方案 分析并推导出问题的解决方案。这一步应该被有意识地分隔出来,不要与编码步骤混淆。也就是说,当你在分析和推导问题的解决方案时,不要考虑任何与实现相关的事情。不要考虑如何编写代码,使用什么库,定义什么变量,或者需要多少层循环。只专注于如何逻辑地解决问题。 这样做可以大大减轻你的心理负担,并使你能够高效地解决问题。至于如何把想法转化为代码,可以放在下一步,分开来做。

  3. 把思路转化为代码 只有在你确定你已经完全理解了问题,并且分析并推导出了它的解决方案,你才可以开始考虑如何把你的想法转换成代码。事实上,将想法转换为代码可以成为一个单独的步骤,而且它也是实际工作中非常重要的能力。

    有时,把想法转化为算法是容易而自然的;然而,有时,将某些想法转化为代码可能非常困难。也许你有过这样的经历,分析和推导花了不到十分钟的时间,但是代码却花了半小时还写不完。

    如何定义变量,保存状态,使用递归或循环加辅助数据结构等,都是在将想法转化为代码时需要做的事情。这种能力也需要刻意练习。