这次的比赛真心翻大车了,简直了,而且翻车的理由特别奇葩:因为题目过于简单。。。
唉,看了一下,第一名的大佬花了8分多点就搞定了,然后我为了图快结果没有想到特别清楚,然后居然错了3次,而且奇葩的是3次都是非常坑爹的错误,结果就彻底滑铁卢了,本来花了50分钟,还算勉勉强强能够接受,结果硬生生变成了1小时5分,国内排名掉了近150名,然后世界排名直接掉了400+,唉,我粗心的毛病倒是啥时候才能彻底改掉啊。。。
btw,这次的比赛成绩是国内434,世界1089,很悲剧地没能进入前10%,真的是不甘心啊!!!
以后还是不能急啊,心急是吃不了热豆腐的,唉。。。
好吧,后来发现是我运气好,第四题我的解法事实上是有漏洞的,写博客的时候整理思路才发现,万幸的是测试样例不够全面,侥幸逃过一劫,运气好,运气好。。。
运气好个球,简直了,突然发现leetcode好像发现了测试样例不全,然后直接取消了我第四题的成绩,判定我第四题没做出来,然后我的排名就莫名其妙地降到国内1000名附近了!
简直了,先不说他们是怎么发现的测试样例不全的这个问题,但凡给我一个看一个错误样例我也能直接改回来啊,又不是什么难题,而且还是他们自己的工作失误,居然直接这么处理,真的是简单粗暴,一整天的好心情突然地就被毁掉了,F**K!
给出题目一的试题链接如下:
这一题的解题思路极其直白,直接将list当中的字符串进行拼接之后比较最终的拼接结果即可。
给出最终的python代码实现如下:
class Solution:
def arrayStringsAreEqual(self, word1: List[str], word2: List[str]) -> bool:
return "".join(word1) == "".join(word2)
一行代码的事,提交代码评测得到:耗时44ms,占用内存14.2MB。
给出题目二的试题链接如下:
这一题当然可以使用递归方式来实现,但是更直接的是我们直接对答案进行构造,因为显然最终答案的构造方式就是在前面尽可能多地填入a
。
假设最终的结果中a
有 x x x个,z
有 z z z个,其他填充字符(恰好一个)为y
,则有:
{ x ⋅ 1 + 1 ⋅ y + z ⋅ 26 = k x + 1 + z = n \left\{ \begin{aligned} x \cdot 1 + 1 \cdot y + z \cdot 26 = k \\ x + 1 + z = n \end{aligned} \right. { x⋅1+1⋅y+z⋅26=kx+1+z=n
变换得到:
y + 25 ⋅ z = k − n + 1 y + 25 \cdot z = k-n+1 y+25⋅z=k−n+1
其中,y的取值范围为1~26。
因此,我们可以求解得到:
{ z = ⌊ k − n + 1 25 ⌋ i f y > 1 z = ⌊ k − n + 1 25 ⌋ − 1 i f y ≤ 1 \begin{cases} z = \lfloor{\frac{k-n+1}{25}}\rfloor & if \ y > 1 \\ z = \lfloor{\frac{k-n+1}{25}}\rfloor -1 & if \ y \leq 1 \end{cases} { z=⌊25k−n+1⌋z=⌊25k−n+1⌋−1if y>1if y≤1
给出python代码实现如下:
class Solution:
def getSmallestString(self, n: int, k: int) -> str:
z = (k-n+1) // 25
y = (k-n+1) % 25
if y <= 1 and z > 0:
y += 25
z -= 1
x = n-z-1
return x*'a' + chr(ord('a')+y-1) + z*'z'
提交代码评测得到:耗时40ms,占用内存15.2MB。
当前的最优代码实现耗时24ms,不过看了一下本质上也就是直接求,不过他似乎对y和z的确定方式有了更进一步的优化,有兴趣的读者可以自行去看一下,这里就不过度展开了。
给出题目三的试题链接如下:
第三题是我这次翻车翻的最大的一道题,浪费了巨长的时间,就是为了偷懒,结果偷鸡不成蚀把米,唉。。。
这道题的思路其实非常的直接,就是遍历每一个值,考虑每一个值被删除之后的变化。
当每个值被删除之后,后面一个值会补上,因此后方数字的id的奇偶性就会全部发生反转,因此,我们只需要记录前方的所有同奇偶性的数字之和后方异奇偶性的数字之和是否和前方所有异奇偶性的数字之和和后方所有同奇偶性的数字之和。
唯一需要注意的一点就是边际问题,这个仔细一点就行了。
给出python代码实现如下:
class Solution:
def waysToMakeFair(self, nums: List[int]) -> int:
n = len(nums)
l = [0 for i in range(n+2)]
r = [0 for i in range(n+2)]
for i in range(n):
l[i+2] = l[i] + nums[i]
r[n-i-1] = r[n-i+1] + nums[n-i-1]
ans = 0
for i in range(n):
if l[i+1]+r[i+2] == l[i] + r[i+1]:
ans += 1
return ans
提交代码评测得到:耗时1644ms,占用内存23.7MB。
当前最优的代码实现耗时1356ms,看了一下他的实现思路,应该是一样的,反正都是 O ( N ) O(N) O(N)的算法复杂度,就不多做展开了。
给出题目四的试题链接如下:
额,突然发现,这次是运气比较好,比赛的时候给的解法虽然通过了测试,但是实际是有点问题的。。。
唉,运气比较好,运气比较好。。。
真实的解法和我们一开始的思路其实大差不差。首先,要想完成全部的任务,那么显然所需的能量至少是所有任务实际所需的能量,然后的关键就是考虑需要补足的差额。
有关差额的选择,我们需要关联tasks的选择顺序,显然,差额越大的,我们需要在能量还足够的时候尽早地全部完成,然后同样差额的情况下,那么需要能量越大的,我们希望趁着能量还足够,就趁早完成。
从而,我们对tasks进行排序,然后计算所需的能量差额即可。
给出最终的代码实现如下:
class Solution:
def minimumEffort(self, tasks: List[List[int]]) -> int:
tasks = sorted(tasks, key=lambda x: (x[1] - x[0], x[1]), reverse=True)
cost = sum(x[0] for x in tasks)
remain = cost
for x, y in tasks:
if remain < y:
cost += y - remain
remain = y
remain -= x
return cost
提交代码评测得到:耗时1284ms,占用内存59.5MB。
当前最优的代码实现耗时1248ms,看了一下,整体是差不多的,就不过多展开了。