• LeetCode笔记:Biweekly Contest 37

    • 0. 赛后总结
    • 1. 题目一
      • 1. 解题思路
      • 2. 代码实现
    • 2. 题目二
      • 1. 解题思路
      • 2. 代码实现
    • 3. 题目三
      • 1. 解题思路
      • 2. 代码实现
      • 3. 算法优化
    • 4. 题目四
      • 1. 解题思路
      • 2. 代码实现

0. 赛后总结

这一次的比赛真心是五味陈杂,看排名吧,也不算低,国内200,全球500多点,也不算差,即使考虑到晚场的参赛人数少一点,也多少在前10%靠近前5%,不算是个太丢脸的成绩。

但是,无论如何,只做出两题这种情况无论在何时都不是一个让人开心的结果,尤其最后两题遇到的还都是超时问题,后面半个多小时真的是看着题目发呆,横竖不知道该怎么修改,硬生生地最后被用完了时间。

感觉以后做题目的时候还是要好好考虑一下代码的实现效率了,老是这么搞下去迟早有一天把自己搞废了。。。

1. 题目一

给出题目一试题链接如下:

  • 5122. 删除某些元素后的数组均值

1. 解题思路

这一题最直接的思路就是直接按照题目说的,排序之后去除掉头部的5%数据和尾部的5%的数据,然后求一下平均就是了。

2. 代码实现

给出python代码实现如下:

import numpyclass Solution:def trimMean(self, arr: List[int]) -> float:n = len(arr) // 20arr = sorted(arr)return numpy.mean(arr[n:-n])

提交代码评测得到:耗时112ms,占用内存28.6MB。

2. 题目二

给出题目二试题链接如下:

  • 5528. 网络信号最好的坐标

1. 解题思路

这一题不知道有没有更好的解题思路,反正我拿到之后的第一反应就是直接暴力检索一下,万幸,没有超时,所以就结束了。

2. 代码实现

给出python代码实现如下:

import mathclass Solution:def bestCoordinate(self, towers: List[List[int]], radius: int) -> List[int]:strength = defaultdict(float)for x0, y0, q0 in towers:for x in range(x0-radius, x0+radius+1):for y in range(y0-radius, y0+radius+1):if (x-x0)**2 + (y-y0)**2 > radius**2:continued = math.sqrt((x-x0)**2 + (y-y0)**2)q = int(q0 / (1+d))strength[(x, y)] += qans = sorted(strength.items(), key=lambda x: (-x[1], x[0]))return list(ans[0][0])

提交代码评测得到:耗时5544ms,占用内存19.4MB。

当前最优代码耗时2504ms,他的解法比较暴力,但是针对某些情况确实会更有效率。

他的解法是直接遍(0,0)(0,0)(0,0)到(50,50)(50,50)(50,50)内的左右坐标点,由于圆心均在这个范围内,因此,这个区域外的点上的信号叠加效果一定低于这个区域内部的点,因此,只需要遍历这部分坐标点即可。

感觉这个解法有点针对题目取巧了,不够通用,不过还是多少有一点参考价值的。

3. 题目三

给出题目三试题链接如下:

  • 5527. 大小为 K 的不重叠线段的数目

1. 解题思路

这一题直觉上一看就是一道动态规划的题目,于是就用了缓存机制直接快速地实现了一个动态规划的算法,然而不幸的是,解法超时了,知道最后都没能搞定。

所以,这里,我们先给出我们的动态规划解法,然后看看大佬们的算法优化方案吧。

我们的动态规划核心思路是说,每一次给出一个终止切割点ed,然后对于这一个切割,显然前面有ed种切割起点的选择方法(0 ~ ed-1),因此,我们可以给出递推公式如下:

dp(n,k)=∑ed=1n−1ed×dp(n−ed,k−1)dp(n, k) = \sum_{ed=1}^{n-1}{ed \times dp(n-ed, k-1)}dp(n,k)=ed=1∑n−1​ed×dp(n−ed,k−1)

特别的,当k=1k=1k=1时,有dp(n,1)=n×(n−1)/2dp(n, 1) = n\times (n-1) / 2dp(n,1)=n×(n−1)/2。

2. 代码实现

给出我们的代码实现如下:

class Solution:def numberOfSets(self, n: int, k: int) -> int:MOD = 1000000007@lru_cache(None)def dp(n, k):if k <= 1:return n * (n-1) // 2elif k == n-1:return 1ans = 0for ed in range(1, n-k+1):ans += ed * dp(n-ed, k-1)return ans % MODreturn dp(n, k)

但是,上述代码会出现超时问题,68个测试样例只能通过60个。

3. 算法优化

考察了大佬们的算法之后,发现我们的算法事实上和正确解法之间只有一步之遥,真的是伤心。

上述算法如果不使用缓存方式来实现,那么可以写作:

class Solution:def numberOfSets(self, n: int, k: int) -> int:MOD = 1000000007dp = [[0 for i in range(n+1)] for _ in range(k+1)]for i in range(1, n+1):dp[1][i] = i*(i-1) // 2for i in range(2, k+1):dp[i][i+1] = 1for j in range(i+2, n+1):for t in range(1, j):dp[i][j] += t * dp[i-1][j-t]return dp[k][n]

可以看到,算法复杂度是O(k×n2)O(k \times n^2)O(k×n2)。

但是,核心在于递推公式,事实上,我们可以将递推公式改写为:

dp(n,k)=∑i=1n−1i×dp(n−i,k−1)=∑i=1n−1(∑j=1idp(j,k−1))=dp(n−1,k)+∑j=1n−1dp(j,k−1)dp(n, k) = \sum_{i=1}^{n-1}{i \times dp(n-i, k-1)} \\ = \sum_{i=1}^{n-1}{(\sum_{j=1}^{i}dp(j, k-1))} \\ = dp(n-1, k) + \sum_{j=1}^{n-1}dp(j, k-1) dp(n,k)=i=1∑n−1​i×dp(n−i,k−1)=i=1∑n−1​(j=1∑i​dp(j,k−1))=dp(n−1,k)+j=1∑n−1​dp(j,k−1)

那么,我们只需要再用一个数组来储存∑j=1n−1dp(j,k−1)\sum_{j=1}^{n-1}dp(j, k-1)∑j=1n−1​dp(j,k−1)的值,就可以减少一次循环次数,将复杂度降至O(k×n)O(k \times n)O(k×n)。

给出最终的代码实现如下:

class Solution:def numberOfSets(self, n: int, k: int) -> int:MOD = 1000000007dp = [[0 for i in range(n+1)] for _ in range(k+1)]dps = [[0 for i in range(n+1)] for _ in range(k+1)]for i in range(1, n+1):dp[1][i] = i*(i-1) // 2dps[1][i] = dps[1][i-1] + dp[1][i]for i in range(2, k+1):dp[i][i+1] = 1dps[i][i+1] = 1for j in range(i+2, n+1):dp[i][j] = (dp[i][j-1] + dps[i-1][j-1]) % MODdps[i][j] = (dps[i][j-1] + dp[i][j]) % MODreturn dp[k][n]

提交代码评测得到:耗时1312ms,占用内存63.1MB。

4. 题目四

给出题目四的试题链接如下:

  • 5530. 奇妙序列

1. 解题思路

这一题我直接的思路是肯定不可能直接暴力地每次去修改已有的数,否则一定会有超时问题,为了规避这个问题,我的思路是存的时候只存原值,但是将操作另行记录,然后返回的时候只要将原数取出,然后加上后续的操作即可。

但是,这样同样会有一个问题,就是当后续的操作非常多的时候,也会存在超时问题。

比赛结束之后看了一下大佬们的解法,其中有一个解法特别的优雅,他的思路是在存取和读出时各自做一次操作。

存取时,令y=(x−α)/βy = (x - \alpha) / \betay=(x−α)/β,而后存取y;读取时,只要返回y×β+αy \times \beta + \alphay×β+α。然后,我们在操作时针对α\alphaα和β\betaβ进行操作,这样,所有在数据加入之后的后续操作都会在返回时反映出来,而在此之前的操作由于α\alphaα和β\betaβ的变化都不会被记录在案,因此每个数据只会记录加入之后变化。

但是,如果单纯是除法的话,python后续会遇到精度问题,最终会导致结果错误,因此,该算法中将变化过程修改为了:

y = (x-a) * pow(b, -1, 1e9+7)

其中,pow(x, -1, m)为python 3.8之后加入的新的功能,其含义是求解方程x×ymod(m)≡1x \times y \mod(m) \equiv 1x×ymod(m)≡1中yyy的值。

这样,就修改上述变化公式为:
y=(x−α)×β′xret=y×β+αβ×β′mod(109+7)≡1y = (x - \alpha) \times \beta' \\ x_{ret} = y \times \beta + \alpha \\ \beta \times \beta' \mod (10^9+7) \equiv 1 y=(x−α)×β′xret​=y×β+αβ×β′mod(109+7)≡1

2. 代码实现

给出最终的python代码实现如下:

class Fancy:def __init__(self):self.L=[]self.coef=[1,0]def append(self, val: int) -> None:val=(val-self.coef[1])%(10**9+7)val=(val*pow(self.coef[0], -1, 10**9+7))%(10**9+7)self.L.append(val)def addAll(self, inc: int) -> None:self.coef[1]=(self.coef[1]+inc)%(10**9+7)def multAll(self, m: int) -> None:self.coef[0]=(self.coef[0]*m)%(10**9+7)self.coef[1]=(self.coef[1]*m)%(10**9+7)def getIndex(self, idx: int) -> int:if idx not in range(len(self.L)):return -1else:return (self.L[idx]*self.coef[0]+self.coef[1])%(10**9+7)

该解法来自于lilidavid大佬,提交代码评测得到:耗时952ms,占用内存50.3MB,属于当前最优的算法之一。

不得不说,大佬真的是强,这个解法真心佩服得五体投地。

LeetCode笔记:Biweekly Contest 37 比赛记录相关推荐

  1. LeetCode笔记:Biweekly Contest 38 比赛记录

    LeetCode笔记:Biweekly Contest 38 0. 赛后总结 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 ...

  2. LeetCode笔记:Biweekly Contest 33 比赛记录

    LeetCode笔记:Biweekly Contest 33 0. 赛后总结 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 ...

  3. 【LeetCode】Biweekly Contest 10 总结

    一.概述 做的很差劲,至少可以拿出半小时看第四题的,结果只ac了第一题和第三题.所以对自己很生气,要总结一下经验教训. 二.分析 1.第一题 输入三个有序数组,找相同元素. 我是个傻逼,为什么这么说呢 ...

  4. LeetCode笔记:Biweekly Contest 85

    LeetCode笔记:Biweekly Contest 85 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 2. 代码实现 ...

  5. LeetCode笔记:Biweekly Contest 84

    LeetCode笔记:Biweekly Contest 84 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 2. 代码实现 ...

  6. LeetCode笔记:Biweekly Contest 83

    LeetCode笔记:Biweekly Contest 83 0. 小结 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 2. ...

  7. LeetCode笔记:Biweekly Contest 94

    LeetCode笔记:Biweekly Contest 94 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 2. 代码实现 ...

  8. LeetCode笔记:Biweekly Contest 88

    LeetCode笔记:Biweekly Contest 88 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 2. 代码实现 ...

  9. LeetCode笔记:Biweekly Contest 91

    LeetCode笔记:Biweekly Contest 91 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 2. 代码实现 ...

  10. LeetCode笔记:Biweekly Contest 82

    LeetCode笔记:Biweekly Contest 82 1. 题目一 1. 解题思路 2. 代码实现 2. 题目二 1. 解题思路 2. 代码实现 3. 题目三 1. 解题思路 2. 代码实现 ...

最新文章

  1. 服务器如何开启远程控制,远程控制命令设置方法介绍
  2. LInux主机与虚拟机网络链接
  3. word无法打开请去应用商店_word文档打不开的4种解决方法
  4. tomcat 启动时内存溢出
  5. FreeSql (三十二)Aop
  6. 动态规划 最长上升子序列
  7. 字符缓冲流 读写数据
  8. 列车时刻管理c语言程序设计,列车时刻表信息管理系统实践报告C语言源代码
  9. php扩展拦截请求,PHP的拦截器实例分析
  10. pbewithmd5anddes算法 对应.net_「AI」目标检测第一话:R-CNN和SPP-Net
  11. 万兆网文件服务器,万兆以太网网卡网吧服务器中的应用
  12. 现代操作系统 第三章 内存管理 习题答案
  13. 计算机功能自定义,电脑鼠标自定义按键设置方法
  14. Unity 防止数组索引越界的几种方法
  15. Spotfire 聚合筛选 会污损行数据
  16. python3 sorted自定义排序的函数
  17. BP神经网络综合评价法
  18. 数据安全治理方法导论
  19. Linux操作命令分类详解 - 压缩备份(四)
  20. shell 亚瑟王环

热门文章

  1. 玩转算法与数据结构 C++描述 选择排序
  2. codelite编译器配置
  3. Mysql的原子性、持久性原理
  4. What The F**k Python!!!
  5. 装了伽卡他卡打不开任务管理器的解决办法
  6. 想成为挣钱的游戏程序员要经历多少阶段?
  7. 变压器励磁模型 Matlab/simulink 可用于模拟电压暂降等电能质量问题
  8. InstallShield vs2015 的安装与激活
  9. ubuntu服务器网站备份,备份云服务器ubuntu系统
  10. Tableau实战 网站客户细分仪表盘