LeetCode weekly contest 242
YoungForest · https://youngforest.github.io/2021/05/23/LeetCode-weekly-contest-242/
文章目录 · 4 节
| Rank | Name | Score | Finish Time | Q1 (3) | Q2 (5) | Q3 (5) | Q4 (6) |
|---|---|---|---|---|---|---|---|
| 165 / 12400 | YoungForest | 18 | 1:07:14 | 0:03:22 🐞1 | 0:16:01 🐞1 | 0:27:41 🐞1 | 0:52:14 |
提前40min AK。虽然因为粗心大意,前三题每题WA一次,导致15min罚时,但好的一点是这周应该不用每天残酷打卡了。正好全力以赴,准备周三的硕士论文答辩。
三年的硕士生涯全靠周三一天了,毕其功于一役,加油,Forest!
1869. Longer Contiguous Segments of Ones than Zeros
签到题。统计连续字串的长度,更新最长长度即可。
因为更新最长长度的代码写错位置,写到了if的分支里,WA了一次。应该无论如何都要更新,所以要写在外面。
1 | class Solution { |
时间复杂度: O(N),
空间复杂度: O(1).
1870. Minimum Speed to Arrive on Time
直接暴力二分怼。之前总结的binary search模版很好用。基本只需要改几行代码就行了。
因为浮点数精度WA了一次。10^-5 不够小,建议以后都用10^-9。
1 | class Solution { |
时间复杂度: O(log dist[i] * dist.length) = log 10^5 * 10^5,
空间复杂度: O(1).
1871. Jump Game VII
很容易想到暴力的N^2解法。
从头开始遍历,如果是0的话,更新之后所有可以到达的位置。
时间复杂度为: s.length * (maxJump - minJump) = 10% * 10^5.
优化的方向是“更新之后所有可以到达的位置”。显然,这步更新因为有很多重复的更新,因此花费很多。但是,我们考虑每次其实是更新一个区间(range),而且区间的大小相等,而且区间总是向右移动的。因此,我们发现,更新区间并不需要遍历minJump…maxJump,只需要从maxJump向前开始遍历,如果和之前已经更新过的区间重合了,就直接break结束更新就好了。因为每个位置最多被更新一次,因此时间复杂度是 s.length.
1 | class Solution { |
时间复杂度: O(s.length),
空间复杂度: O(s.length).
1872. Stone Game VIII
类似之前的Stone Game,这种最优玩法的题目大多数属于 动态规划问题。
即通过搜索所有可能的选择,找到最优结果。过程中有很多重复子问题,因此需要使用动态规划。
最优化目标是(Alice’s score - Bob’s score),Alice想要最大化,Bob想要最小化。其实都是最大化(我的分数 - 对方的分数)。
另外,观察到操作的结果其实是石头的和,因此需要提前计算前缀和数组。
问题转化成,从前缀和[i:]中挑一个数,使得的分数差最大;之后的后手只能从被挑的位置之后挑。
定义
dp(i) 为从前缀和[i:]中挑一个数的最大分数差,
则状态转移方程为:
dp(i) = max(presum[j] + dp(j + 1) for j in range(i,)).
时间复杂度为 O(N^2), 显然超时。
然而,在状态转移方程中其实还有重叠子问题, for loop max可以只计算一次,因此可以进一步优化到 O(N).
1 | class Solution { |
时间复杂度: O(N),
空间复杂度: O(N).