2021年的学习目标
年初制定的21年学习计划中,将算法之美加入了今年的重点内容。模仿万达老王的语气,先给自己制定一个小目标,年底前力扣刷题300+。只要坚持leetcode每日一题满勤,这个小目标基本就可以达成了。
之前其实是比较讨厌算法的,枯燥无趣、费时费脑,但没办法,算法已经成为各大公司面试必考的内容,只能硬着头皮刷题了。
在算法方面,个人觉得当前的水平大概就是,站在彩笔儿子的边缘疯狂突击,然后突不出去......
之后一段时间,重点会放在算法刷题,与相关技巧分享方面。今天就先来分享一个前期新手刷题的小技巧,能帮你减少代码提交次数,提升代码提交通过率。
如何验证代码正确性
拿我今天Leetcode打卡的每日一题 1438. 绝对差不超过限制的最长连续子数组 题目来说:
给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。
如果不存在满足条件的子数组,则返回 0 。
示例 1:
输入:nums = [8,2,4,7], limit = 4
输出:2
解释:所有子数组如下:
[8] 最大绝对差 |8-8| = 0 <= 4.
[8,2] 最大绝对差 |8-2| = 6 > 4.
[8,2,4] 最大绝对差 |8-2| = 6 > 4.
[8,2,4,7] 最大绝对差 |8-2| = 6 > 4.
[2] 最大绝对差 |2-2| = 0 <= 4.
[2,4] 最大绝对差 |2-4| = 2 <= 4.
[2,4,7] 最大绝对差 |2-7| = 5 > 4.
[4] 最大绝对差 |4-4| = 0 <= 4.
[4,7] 最大绝对差 |4-7| = 3 <= 4.
[7] 最大绝对差 |7-7| = 0 <= 4.
因此,满足题意的最长子数组的长度为 2 。
示例 2:
输入:nums = [10,1,2,4,7,2], limit = 5
输出:4
解释:满足题意的最长子数组是 [2,4,7,2],其最大绝对差 |2-7| = 5 <= 5 。
示例 3:
输入:nums = [4,2,2,2,4,4,2,2], limit = 0
输出:3
提示:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^9
0 <= limit <= 10^9
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
在这里吐槽下,这是一道中等难度的题目,但坦白说如果之前没有做过相关类型的题目,对新手来说真的是有些困难,它的通过率只有48.3%。尤其后来看到官方的解题说明,居然提倡使用sortedcontainers的SortedList方法,要知道这个模板可不是python自带的原生模板,需要安装后才能使用的。按照这个说法numpy、pandas我也装下,还玩什么算法...
按照简单题我重拳出击,中等题我投石问路的思维。免不了要造一些测试用例去验证自己的代码是否覆盖了所有场景。如果是平时咱们会怎么去测试?是否如下面这样验证:
from typing import List class Solution: def longestSubarray(self, nums: List[int], limit: int) -> int: ... return num if __name__ == '__main__': s = Solution() # 打印结果是否为2 print(s.longestSubarray([8, 2, 4, 7], 4)) # 或者对结果进行条件判断 result = s.longestSubarray([8, 2, 4, 7], 4) if result != 2: print("failure") else: print("success")
如果换一个用例呢,修改内容,重新执行?下一个用例发现存在错误,修改后通过了,那么之前的用例是否需要再验证下,修改后能否通过,太费事了!
为了方便,我创建了一个简单的循环用例用于批量校验测试用例组,从而提升代码覆盖场景,提高代码提交通过率。
Pycharm代码模板
Python最好用的IDE一直以来都是大家比较热衷讨论的话题,喜欢DIY的朋友偏爱VS Code 和Jupter Notebook。但关注功能全面、拿来即用的人,更多的首选Pycharm。作为懒人界的扛把子,从学习python的第一天就一直是Pycharm重度使用者。
那么,使用pycharm能为我们算法刷题,带来什么便利呢?这就不得不提Pycharm的Live Templates(实时代码模板)了。
实时代码模板能让我们更加高效的通过固定模式的代码块导入,提高编码效率,同时也可以增加个性化。代码模板的调用有两种方式:
- 在明确代码模板abbreviation(缩写词)的前提下,快捷输入缩写名称后按 Tab 键,导入模板。
- 按 Ctrl + J 则会先提示与之匹配的实时代码模板介绍,然后按 Enter 完成预设语句的生成。
比如我们最常用的生成main方法的快捷示例:
main模板导入
今天就教大家做一个刷题专用的自验用例模板,用以提升刷题效率。
首先我们进入依次点击pycharm的File > Settings > Editor > Live Templates , 找到Python,然后创建Live Template。如下图所示:
常见模板
创建模板后,我们需要加入准备好的代码模板,内容如下:
from typing import List $CLASS_DEMO$ if __name__ == '__main__': s = Solution() test_list = [ ] for test_index, test_case in enumerate(test_list, start=1): *test, result = test_case test_result = s.$END$(*test) if test_result != result: raise ValueError("\n testcase %d error:\n expect: %s \n actually %s" % (test_index, result, test_result)) print("test_case %d succeed." % test_index)
Abbreviation是设定我们在代码编写时倒入模板的缩写词,根据大家个人习惯填写。然后粘贴上面的代码模板到Template text框体内,最后在Application in Python中选择Other后,保存即可。
保存模板
那么,这个模板到底有什么用途呢?让我们来看看效果。
快捷模板的使用
Leetcode针对Python在右侧的解题框体中会给出默认的代码入口,比如这样:
class Solution: def longestSubarray(self, nums: List[int], limit: int) -> int:
此时我们复制代码段,然后进入pycharm,创建解题模板:
调用leetcode模板
我们只需5秒钟时间就创建好了解题模板,下来看看模板的使用效果吧:
我们正常编写完成代码后,将题目给我们提供的三组测试用例,填写如test_list中,并在每组用例结果加入预期结果。比如 第一组的入参nums为列表,limit为4,预期结果为2,我们将其组成列表填写,后续用例仿照格式依次完成。
执行效果
然后,我们执行代码,程序会将我们准备的所有用例进行依次执行,并返回结果。如果基础用例不够,我们还可以自己设计一些边界、异常等条件的测试用例组添加入test_list中。
那么如果代码与用例结果不符合会如何?来看看下面的演示:
错误提示
我们可以很清楚的知道哪个用例执行错误,错误的结果是什么。
通过使用模板,可以对我们的算法解题,提供更高效的自验用例排查,大大缩减了我们调试代码的时间。不信你瞧:
坚持Leetcode打卡
大家觉得是否有所帮助呢,还不快配置到你的pycharm上,开启刷题之旅?