0. 赛后总结
这一次的比赛久违的直接把4道题全部做出来了,耗时差不多40分钟,国内和国际排名都在前2%这个量级,就是很开心啦。
继续加油吧!😄
1. 题目一
给出题目一的试题链接如下:
1. 解题思路
这一题思路上来说非常的直接,仅一次交换就能使两字符串相同的充要条件为:
- 两字符串要么字符完全相同,要么有且只有两个位置字符不同,且两者位置刚好相反。
因此,我们基于此进行代码写作即可。
2. 代码实现
给出python代码实现如下:
class Solution:
def areAlmostEqual(self, s1: str, s2: str) -> bool:
n, m = len(s1), len(s2)
if n != m:
return False
diff = []
for i in range(n):
if s1[i] != s2[i]:
diff.append(i)
if len(diff) == 0:
return True
if len(diff) == 2 and s1[diff[0]] == s2[diff[1]] and s1[diff[1]] == s2[diff[0]]:
return True
return False
提交代码评测得到:耗时20ms,占用内存14.3MB。
2. 题目二
给出题目二的试题链接如下:
1. 解题思路
这一题其实也挺简单的,因为题目限定了图必须为星型图,因此必满足条件:
- 有且只有一个节点的度数不为1,其度数为 n − 1 n-1 n−1。
因此,我们可以同样快速地给出代码实现。
2. 代码实现
给出python代码实现如下:
class Solution:
def findCenter(self, edges: List[List[int]]) -> int:
cnt = defaultdict(int)
for u, v in edges:
cnt[u] += 1
cnt[v] += 1
res = [x for x in cnt if cnt[x] != 1][0]
return res
提交代码评测得到:耗时860ms,占用内存50.6MB。
当然,你也可以直接判断如果某一个点的度数超过了1,然么直接返回这个节点即可,这样可以更进一步的对时间复杂度进行优化。
3. 题目三
给出题目三的试题链接如下:
1. 解题思路
这一题算是我这次比赛中耗时最长的一道题目了,本质上来说这是一道数学题,需要通过不等式关系预先确定一下人员的分配策略。
可以我大致推导了一下没能弄出来,盲猜了一些关系似乎也对不上号,所以想想就算了,就直接暴力一点进行解答,每次考察每一个人的情况。
考察对每一个班加入一个人(假设原先有 b b b个人,考试通过有 a a a个人),则其通过率的变化为:
δ p = a + 1 b + 1 − a b = b − a b ⋅ ( b + 1 ) \delta p = \frac{a+1}{b+1} - \frac{a}{b} = \frac{b-a}{b \cdot (b+1)} δp=b+1a+1−ba=b⋅(b+1)b−a
因此,我们只需要基于 b − a b ⋅ ( b + 1 ) \frac{b-a}{b \cdot (b+1)} b⋅(b+1)b−a对所有的班级进行排序,然后每次加入一个人即可。
该算法的复杂度为 O ( m ⋅ l o g n ) O(m \cdot logn) O(m⋅logn),其中, n , m n,m n,m分别为班级数以及可以添加的学生数目。
2. 代码实现
给出python代码实现如下:
import numpy
class Solution:
def maxAverageRatio(self, classes: List[List[int]], extraStudents: int) -> float:
classes = sorted(classes, key=lambda x: (x[1]-x[0])/(x[1]*(x[1]+1)), reverse=True)
cache = [(-(b-a)/(b*(b+1)), a, b) for a, b in classes]
heapq.heapify(cache)
for _ in range(extraStudents):
_, a, b = heapq.heappop(cache)
a += 1
b += 1
heapq.heappush(cache, (-(b-a)/(b*(b+1)), a, b))
return numpy.mean([a/b for _, a, b in cache])
提交代码评测得到:耗时2776ms,占用内存80.8MB。
但是我相信可以有更直接的人员安排策略,如果有想清楚的朋友请务必在评论区里面解说一二,大谢!
4. 题目四
给出题目四的试题链接如下:
1. 解题思路
这次的最后一题作为一到hard的题目来说的话就有一点水啦,说穿了只要参考双向指针的方法,实现确定i,j两个位置,然后不断地更新i,j两个指针的位置,并计算每一种情况下的分数即可。
显然,i,j的维护规则为:
- 当
nums[i] < nums[j]
时,向外滑动j
可以获得更大的分数,反之滑动i
。
因此,我们在 O ( N ) O(N) O(N)的算法复杂度下就可以完成这一题的解答。
2. 代码实现
给出python代码实现如下:
class Solution:
def maximumScore(self, nums: List[int], k: int) -> int:
i, j, n = k, k, len(nums)
_min = nums[k]
res = nums[k]
while i-1 >= 0 and j+1 < n:
if nums[i-1] <= nums[j+1]:
_min = min(_min, nums[j+1])
j += 1
else:
_min = min(_min, nums[i-1])
i -= 1
res = max(res, (j-i+1)*_min)
while i-1 >= 0:
_min = min(_min, nums[i-1])
i -= 1
res = max(res, (j-i+1)*_min)
while j+1 < n:
_min = min(_min, nums[j+1])
j += 1
res = max(res, (j-i+1)*_min)
return res
提交代码评测得到:耗时1320ms,占用内存24.6MB。