第一次LeetCode周赛心得(力扣-cn周赛,使用python3)
第一次力扣参赛:第 174 场力扣周赛
第 174 场力扣周赛赛题:
https://leetcode-cn.com/circle/discuss/lEfEkb/view/OrAJAh/
第 174 场力扣周赛国内排名(点击小图标可查看选手代码):
https://leetcode-cn.com/contest/weekly-contest-174/ranking/1/
总体心得
使用python3,做成了第一道题,第二道题的解超时,便结束了第一次周赛。
下午看了排行榜靠前的参赛者代码,最快的在17分钟内就完赛了(使用python3),使用python3的和c++的数量几乎对半分。
先来说个问题:使用python算作弊吗?
我觉得不算,尽管python中有collections
库这种强大的操作集,但是对不懂数据结构、或没有赛题解决思路的人来说,终究还是没有帮助的。python只是帮助我们把精力全部集中在算法的流程上,而非程序设计与具体实现上(python封装了太多常用操作,减少实现压力)。
况且,c++中也有vector<>()
、java中也有hashtable<>()
这种类似的可调用的数据结构对象,来简化操作。因此,python不算作弊。
我目前的编程,都是为了实现强化学习算法,没有涉及到底层系统或者企业级开发,因此选择用python3来刷力扣。
使用c/cpp来对每个指针进行操作,可能会在算法的时间空间复杂度上有一定优势,但是,实现起来会比较麻烦,而周赛比的是速度。况且,python3中封装的代码都是方法较优的。
这次最快的同学是 zerotrac2 ,看到了其领英上的简历,很强,高中就有极好的竞赛基础,在清华软工有9/74的排名:
这位同学的简历链接:https://www.linkedin.com/in/zerotrac/
看了他的代码,觉得“并不是我现在无法达到的水平”,收获了很多库的使用技巧与设计思想,下面对四道题一一分析。
[1341] 方阵中战斗力最弱的 K 行
很简单的排序问题,我的代码为:
class Solution(object):def kWeakestRows(self, mat, k):""":type mat: List[List[int]]:type k: int:rtype: List[int]"""fighter_dict = dict()r = -1for _ in mat:r += 1# key: row number, value: soldiers_countfighter_dict[r] = sum(mat[r])returns = list()while k > len(returns):current_min_row = fighter_dict.keys()[0]for row in fighter_dict:if fighter_dict[row] < fighter_dict[current_min_row]:current_min_row = rowreturns.append(current_min_row)del fighter_dict[current_min_row]return returns
高手的代码为:
class Solution:def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]:c = [(sum(x), i) for i, x in enumerate(mat)]c.sort(key=lambda x: (x[0], x[1]))return [x[1] for x in c[:k]]
解决思路差不多,但是我没有很坚决地把问题抽象为一个二维排序问题,因此产生了犹豫,并且复杂化了代码实现过程,除此之外,上述代码值得学习的地方还有:
enumerate(list)
返回(索引, 值)
;- 列表的方法
sort(key=lambda x: expression)
用法(升序); list[:k]
灵活运用切片。
我还存在一个问题,就是我的排序是我自己写的(在while
里),我期望达到在线处理的效果,可是时间复杂度还是有O(k×n)O(k \times n)O(k×n)之多。以后遇到需要排序的问题,直接使用list.sort()
算法,在网上查过,python3封装的排序算法应该是最优的(二分法),时间复杂度为O(n×log2n)O(n \times \log_2 n)O(n×log2n)。
[5329] 数组大小减半
我的算法超时了,看不到了,高手代码为:
class Solution:def minSetSize(self, arr: List[int]) -> int:c = collections.Counter(arr)s = 0ans = 0for k, v in c.most_common():s += vans += 1if s * 2 >= len(arr):return ansreturn -1
我学到了:
collection.Counter(arr)
的使用,直接对个元素计数;- top-n 问题使用
most_common()
方法,也是基于collection.Counter
对象的。
[5330] 分裂二叉树的最大乘积
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = Noneclass Solution:def maxProduct(self, root: TreeNode) -> int:def tot(node):if not node:return 0return tot(node.left) + tot(node.right) + node.valdef dfs(node, s):if not node:return 0, 0p1, q1 = dfs(node.left, s)p2, q2 = dfs(node.right, s)p = p1 + p2 + node.valreturn p, max(q1, q2, p * (s - p))s = tot(root)return dfs(root, s)[1] % 1000000007
看懂这个代码着实花了我一点时间,但是以后遇到类似代码不会再让我感到陌生了:
- 就是一个深度优先搜索(bfs)而已;
- 注意上述算法中的
s
值其实没有变过,作者之所以把其作为dfs()
的参数,应该是因为:在一般的dfs()
递归算法中,dfs()
传入的都是(根结点, 参数),其中参数是参与递归过程的; dfs()
的两个返回值分别是:- 该子树的结点和;
- (1)计算以该子树作为断点,独立成根,其产生的和与剩下部分产生的和的乘积的值,(2)与两个子树的该值比较,取最大的,保留,(3)子树的该值是子树与子树的子树的该值进行比较得到的。
- 巧妙地运用递归进行了搜索,没有半行废话。
[5331] 跳跃游戏 V
惊了,大神前三题用的好好的 python3 ,第四题一下就换 cpp 了,是觉得太无聊了,想玩玩花样吗…
我觉得也有这种可能:
- 大神们因为刷题太多,已经有了一个自己的轮子库;
- 遇到新问题,马上抽象总结成一起遇到的问题;
- 把以前的轮子稍加修改便可套用,这道题的兄弟题可能是大神以前使用从 cpp 做过的。
或者,此题使用 python3 可能超时。
class Solution {private:vector<bool> used;vector<int> f;public:void dfs(vector<int>& arr, int id, int d, int n) {// 传址调用 arrif (used[id]) {return;}used[id] = true;f[id] = 1;// 看着像二分法,实际上不是// 就是把小人投放到每个“柱子上”,然后递归跳跃for (int i = id - 1; i >= 0 && id - i <= d; --i) {// i可能等于-1,因此加入i>=0这个判断条件if (arr[id] > arr[i]) {dfs(arr, i, d, n);f[id] = max(f[id], f[i] + 1);}else {break;}}for (int i = id + 1; i < n && i - id <= d; ++i) {if (arr[id] > arr[i]) {dfs(arr, i, d, n);f[id] = max(f[id], f[i] + 1);}else {break;}}}int maxJumps(vector<int>& arr, int d) {int n = arr.size();// cpp 中的vertor.size() .resize() 方法库值得积累used.resize(n);f.resize(n);for (int i = 0; i < n; ++i) {dfs(arr, i, d, n);}return *max_element(f.begin(), f.end());// std 的 max_element() 返回指针,操作数也是指针// *max_element 中的星号是取 指针指的值// 而输入的操作数 f.begin() f.end() 表示查找区间范围}
};
我学到了:
dfs()
实际上是一种“挖到最低层的状态结点,然后向上回溯”的过程。在本例中,小人只被投放到了各个结点一次,没有重复计算,当其被投放到最底层结点时,开始计算其步数,并累加至上一层。- 在
for(,条件,)
中增加条件,以保证迭代数在操作体内的可执行性; - cpp 中的vertor.size() .resize() 方法库值得积累;
*max_element()
:std
的max_element()
返回指针,操作数也是指针,*max_element
中的星号是取 指针指的值,而输入的操作数f.begin(), f.end()
表示查找区间范围。
cpp 的结果为:
- 127/127 cases passed (68 ms)
- Your runtime beats 100 % of cpp submissions
- Your memory usage beats 100 % of cpp submissions (10.5 MB)
而使用 python 的结果为:
- 127/127 cases passed (1060 ms)
- Your runtime beats 100 % of python3 submissions
- Your memory usage beats 100 % of python3 submissions (14.2 MB)
(可见,同结构的数据与相同的算法下,python 比 cpp 慢很多)
python 的代码是我自己写的,如下:
class Solution:def maxJumps(self, arr: List[int], d: int) -> int:f = [0 for _ in range(len(arr))]def dfs(arr, index, d, n):if f[index]:return Nonef[index] = 1# left indexesi = index - 1while i >= 0 and index - i <= d:if arr[index] > arr[i]:dfs(arr, i, d, n)f[index] = max(f[index], f[i] + 1)else:breaki -= 1# right indexesi = index + 1while i < n and i - index <= d:if arr[index] > arr[i]:dfs(arr, i, d, n)f[index] = max(f[index], f[i] + 1)else:breaki += 1length = len(arr)for i in range(length):dfs(arr, i, d, length)return max(f)
后记心得
看完了这四道题的“高手”解法,认为明确易懂,且总结了不少规律。我对我自己的实力还是很有信心的。
我不知道我说的对不对:数据结构与算法的基础题,实际上就是一个字“找”,找什么?“解”。解都是找出来的。比的就是谁的方法又巧妙又易于实现(通常,易于实现的算法他人也一看就懂)。有什么好的办法来提升自己吗?刷题、总结、积累。所谓“找”之策,万变不离其宗(数据结构基础),能把问题抽象为已知的经典问题,就可快速解决。
今天周日,下周我想刷刷 LeetCode ,就当娱乐了。下周日的周赛再参加一次,我已经等不及了,说实话。
再后记: 步入“编程的正道”正好一年。去年这时跟着学长实现数学模型,要用到“孤立森林”(不是随机森林,是周志华等人提出的一种无监督离群点判断方法),
matlab
里没有封装好的孤立森林方法(2019年1月份前我只会用matlab
),而python3
的sklearn
库里有,于是入了python3
,编辑器用的PyCharm
,发现比matlab
好用多了。从此,抛弃“伪代码”,钻入底层的世界,学习“配置环境”、“操作系统”、“数据结构”、“编译与字节码”到底是怎么一回事,java
、c/c++
、c#
这种以前或许接触过的却根本不了解的编程语言也被我重新拾起。总之,读了很多很棒的文章,很重视学习编程的规范与底层知识的学习。
这一年里,我写了130+的博文,包括:操作系统&数据结构等等课程的笔记、
python3
的debug心得、编译器配置等等,我的CSDN:https://blog.csdn.net/weixin_42815609。
我还开了不少 GitHub repo,包括强化学习笔记、计算机核心课笔记:
- GitHub 个人主页:https://github.com/PiperLiu
- [更新中…]基于
c/c++
实现的计算机核心课笔记:https://github.com/PiperLiu/CS-courses-notes- [更新中…]强化学习笔记:https://github.com/PiperLiu/Reinforcement-Learning-practice-zh
对了,强烈推荐 VS Code 的插件 LeetCode for VS Code ,今天下午刚刚安装,简直神器。
链接:LeetCode for VS Code: 程序员 Offer 收割利器 - 知乎
PiperLiu
2020-2-2 21:18:04
第一次LeetCode周赛心得(力扣-cn周赛,使用python3)相关推荐
- C#实现力扣双周赛算法题:以组为单位订音乐会的门票订购
目录: 前言: 一,算法题目描述 二,基本概念理解: 三,例子引入分析 四,代码解释 (1)安排座位函数 (2)查询函数 (2)求出1到RPS内的最小下标 (3)gather函数 (4)scatter ...
- 20200507:力扣151周赛下
力扣151周赛下 题目 思路与算法 代码实现 题目 1. 从链表中删去总和值为零的连续节点 思路与算法 只做第三题了,第四题太耗费时间了,第三题对存在的链表进行一个判断就会发现,我们只需要去掉其中相加 ...
- 20200504:力扣187周赛下
力扣187周赛下 题目 思路与算法 代码实现 题目 3.绝对差不超过限制的最长连续子数组 有序矩阵中的第 k 个最小数组和 思路与算法 第三题,本题没什么特殊的东西,滑动窗口即可,注意书写即可. 第四 ...
- 20200501:力扣185周赛上
力扣185周赛上 题目 思路与算法 代码实现 题目 重新格式化字符串 点菜展示表 思路与算法 第一题,重新格式化字符串,没什么难度,直接遍历分类字符和数字,记得统计出数目,数目多1的那一类必须先拼接, ...
- leetcode|经典力扣第一题
今天是 Kevin 的算法之路的第 20 天.为大家讲解 LeetCode 第 1 题,是一道简单但相当经典的题目. 每日一笑 玩游戏第一次坑朋友:对不起我不是故意的. 第二次坑朋友:emmm 第三次 ...
- Leetcode周赛复盘——第 71 场力扣双周赛与第 279 场力扣周赛
双周赛: 5984. 拆分数位后四位数字的最小和 class Solution:def minimumSum(self, num: int) -> int:a, b, c, d = sorted ...
- LeetCode 第 69 场力扣双周赛
5960. 将标题首字母大写 添加链接描述 给你一个字符串 title ,它由单个空格连接一个或多个单词组成,每个单词都只包含英文字母.请你按以下规则将每个单词的首字母 大写 : 如果单词的长度为 1 ...
- 第 338 场周赛 (力扣周赛)
6354. K件物品的最大和 袋子中装有一些物品,每个物品上都标记着数字 1 .0 或 -1 . 给你四个非负整数 numOnes .numZeros .numNegOnes 和 k . 袋子最初包含 ...
- 力扣 双周赛补题 2086. 从房屋收集雨水需要的最少水桶数
文章目录 题目 思路 AC代码 后记 题目 从房屋收集雨水需要的最少水桶数 思路 思路是贪心,因为我们需要从左向右找寻所有的水桶数,所以我们对于每一个房屋都优先判断右边是否能放水桶,右边不能放就看左边 ...
最新文章
- 【OpenCV3】OpenCV3.2.0在VS2013环境下Cmake编译与快速配置
- php ftp 大文件,php – 将文件复制到服务器与FTP之间的文件大小差异
- div设置宽度,实现不等比缩放,或设置最小宽度 min-width
- ExtJS入门(08)窗口,按钮,输入框,
- SAP Spartacus State
- 【Nginx】 Nginx实现端口转发
- c语言占用cpu的程序,Windows下用C语言获取进程cpu使用率,内存使用,IO情况
- O/R Mapping再乱弹
- springmvc请求返回一个字符_Spring MVC框架详解01
- 轻松学SQL Server数据库pdf
- 在VSCode中编辑HTML文档时,在Dom标签上写style属性时智能提示的问题
- 《ANSYS Workbench 14有限元分析自学手册》——1.3 ANSYS 14的界面
- Java 非小数BigDecimal转换为Integer
- 【SDOI 2009】学校食堂 Dining
- Mat 创建图像的理解
- SpringBoot房屋租赁系统
- Convert excel format exception.You can try specifying the ‘excelType‘ yourse-----EasyExcel导入
- Unity序列化——Assets序列化
- SpringMVC -- Restful风格的API
- 基于埋点日志数据的网络流量统计(网站独立访客数(UV)的统计)
热门文章
- 【SQL】结构化查询语言
- ubuntu命令行下中文乱码的解决方案
- 如何分组Windows窗体单选按钮?
- 什么是clearfix?
- 检索每个组中的最后一条记录-MySQL
- Linux技术进阶示意图
- aspx 判断字符串是否为decimal_C++编程技巧: 如何判断输入是否为整型
- python数据导出excel_【python Excel】如何使用python将大量数据导出到Excel中的小技巧之一...
- if/else双分支(JS)
- 实验4-2-8 输出整数各位数字 (15 分)